2012-01-13 2 views
2

У меня есть унаследованный класс C#, который расширяет UIAlertView для запроса пользователю ввести IP-адрес. Он также сохранит IP-адрес и загрузит его в качестве значения ввода по умолчанию.Почему сбой в работе MonoTouch с UIAlertView?

Оригинальный код взломал iOS4.x UIAlertView, чтобы добавить текстовое поле, и у него было несколько проблем с компоновкой. Я преобразовал код, чтобы использовать настройку iOS5 UIAlertViewAlertViewStyle, и все было хорошо.

меня попросили дать ключ Готово на всплывающей клавиатуре, так что это может быть ярлык на кнопку Connect. Я добавил код следующим образом конструктору класса:

public AddressAlertView() 
{ 
    AddButton("Cancel"); 
    AddButton("Connect"); 
    AlertViewStyle = UIAlertViewStyle.PlainTextInput; 

    // NEW - get input text field, enable Done on the keyboard and 
    // allow Done to be the same as the Connect button 
    UITextField fld = GetTextField(0); 
    fld.ReturnKeyType = UIReturnKeyType.Done; 
    fld.ShouldReturn = (textField) => 
    { 
     DismissWithClickedButtonIndex(1, true); 
     return textField.ResignFirstResponder(); 
    }; 
    // *** end of new code *** 

    // restore saved IP address 
    string savedAddress = NSUserDefault.StandardUserDefaults.StringForKey(AddressKey); 
    if (savedAddress != null) 
     fld.Text = savedAddress; 
} 

Класс привыкает как так:

.... 
AddressAlertView addrPrompt = new AddressAlertView(); 
addrPrompt.Title = "IP Address"; 
addrPrompt.Message = "Enter address"; 
addrPrompt.Dismissed += (sender, e) => 
{ 
    if (e.ButtonIndex == 1) 
    { 
     // use IP address... 
     .... 
    } 
}; 
addrPrompt.Show(); 
.... 

Теперь проблема. При запуске этого кода AddressAlertView отображает всплывающее диалоговое окно правильно, и все работает по-прежнему. Однако, если я нажму Готово на клавиатуре, приложение вылетает в UIAlertView.

Я попытался переместить новый код в метод public override void LayoutSubviews(), но он по-прежнему падает.

Любые идеи?

+0

Извините, все еще изучая форматирование комментариев. Догадаться. При просмотре вывода дампа трассировки из MonoTouch упоминалось о некорректном объекте. Вместо того, чтобы получать текстовое поле в качестве локальной переменной, я сохраняю ссылку на него как переменную экземпляра: 'private UITextField _addressTextField = null;' Я изменил код в конструкторе на '_addressTextField = GetTextField (0);'. Это решило крушение. Локальная переменная 'UITextField', несомненно, получала GC'd, вызывая сбои при вызове выражения' ShouldReturn' лямбда. – hypercode

+0

Вы должны сделать свое объяснение ответом и принять свой собственный ответ, чтобы помочь другим, которые ищут решение аналогичной проблемы. Это абсолютно нормально и нужно для StackOverflow. – Krumelur

ответ

1

Вы должны объявить AddressAlertView как член класса:

AddressAlertView addrPrompt; 
public void DoSomething() 
{ 

    addrPrompt = new AddressAlertView(); 
    //etc 

} 

Проблема в этом типе ситуаций (у меня было много подобных с UIAlertViews) является то, что объект является AddressAlertView GC'd и обработчик события вызывает сбой. Чтобы убедиться в этом, ничего не меняйте, просто удалите/прокомментируйте строку addrPrompt.Dismissed += ... и проверьте ее снова. Если это не сбой, это решение.

+1

Да, я обнаружил нечто подобное. См. Мой комментарий выше. Мне не нужно было вводить член класса 'AddressAlertView'. – hypercode

+0

UIAlertView - один из классов, который Monotouch обрабатывает смарт. Вам не нужно держать ссылку на класс. MT позаботится об этом внутренне. – Krumelur

+0

@ Krumelur Это точно? Несколько месяцев назад у меня было много проблем с UIAlertView. Теперь, когда вы упомянули об этом, я снова проверю последнюю стабильную версию. –

0

Согласно документации Apple, вы не должны быть подклассов UIAlertView:

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html

+0

Yup, я знаю слова мудреца Apple в этом вопросе. Я унаследовал этот код, поэтому мне пришлось заставить его работать. Лучший способ сделать этот класс - инкапсулировать 'UIAlertView', а не наследовать его. Кстати, вся ваша работа над камнями MonoTouch. – hypercode

0

Фигурные его. При просмотре вывода дампа трассировки из MonoTouch упоминалось о некорректном объекте. Вместо того, чтобы текстовое поле в качестве локальной переменной, я сохранить ссылку на него в качестве переменной экземпляра:

private UITextField _addressTextField = null; 

Я изменил код в конструкторе:

_addressTextField = GetTextField(0); 

Voila! Это решило крушение. Локальная переменная UITextField, несомненно, получала GC'd, вызывая крах, когда вызывалось выражение lambda ShouldReturn.

Смежные вопросы