Объекты, созданные в области действия ViewDidLoad и которые должны остаться живыми (не подвергаться сборке мусора) после выполнения метода, должны иметь ссылку в содержащем классе.
private UIAlertView _loginScreen; // Declare reference.
private UITextField _usernameField; // Declare reference.
private UITextField _passwordField; // Declare reference.
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
_loginScreen = new UIAlertView(); // Set reference.
_loginScreen.Title = "Login";
_loginScreen.AlertViewStyle = UIAlertViewStyle.LoginAndPasswordInput;
_loginScreen.AddButton ("Cancel");
//username
_usernameField = _loginScreen.GetTextField(0); // Set reference.
_usernameField.KeyboardType = UIKeyboardType.Default;
_usernameField.ReturnKeyType = UIReturnKeyType.Next;
_usernameField.ClearButtonMode = UITextFieldViewMode.WhileEditing;
//password
_passwordField = _loginScreen.GetTextField(1); // Set reference.
_passwordField.KeyboardType = UIKeyboardType.Default;
_passwordField.ReturnKeyType = UIReturnKeyType.Next;
_passwordField.ClearButtonMode = UITextFieldViewMode.WhileEditing;
//(Error SIGSEV happens here!!! and the resignfirstresponder doesn't work)
_passwordField.ShouldReturn = (tf) => // Use reference.
{
// This delegate will be executed at a later time, ensure its owner
// object is rooted with a reference.
tf.ResignFirstResponder();
return true;
} ;
_loginScreen.Show();
}
Пользователь poupou *Конечно, 1005 * был первым, кто ответил на этот вопрос, но я бы хотел добавить его с примером кода, так как эта ошибка меня слишком много кусала.Его сложно отладить, и он может неожиданно произойти после сборки мусора.
Мое эмпирическое правило;всякий раз, когда new
или фабричный метод используется, ссылка должна сохраняться, если объект не выходит из области видимости или уже не вложен в другой объект со ссылкой.
По этой причине я ставлю поля с подчеркиванием, он сигнализирует «этот объект будет жить в пределах областей метода в этом объекте, и его можно легко отличить от переменных метода (без подчеркивания).
Теперь кажется, что для этого случая GetTextField()
создаетобъект-обертка, а не ссылка. Хотя поле loginScreen
является корневым, объект, возвращаемый из GetTextField()
, не является объектом и подвержен сборке мусора. Я бы сказал, что это ошибка в API MonoTouch из-за непредвиденного поведения.