2015-01-19 3 views
6

Я хочу реализовать UITextFieldDelegate в классе, отличном от UIViewController, но когда я это делаю, я получаю исключение EXC_BAD_ACCESS во время выполнения.Реализация UITextFieldDelegate в отдельном классе

Так почему же эту работу:

class MyViewController : UIViewController, UITextFieldDelegate 
{ 
    ... 

    func createUI() 
    { 
    let someTextField: UITextField = UITextField() 
    someTextField.delegate = self 

    ... 
    } 

    func textFieldShouldReturn(textField: UITextField!) -> Bool 
    { 
    textField.resignFirstResponder() 
    return true; 
    } 
} 

Но это вовсе не так:

class MyViewController : UIViewController 
{ 
    ... 

    func createUI() 
    { 
    let someTextField: UITextField = UITextField() 
    someTextField.delegate = MyTextFieldDelegate() 

    ... 
    } 
} 

class MyTextFieldDelegate : NSObject, UITextFieldDelegate 
{ 
    func textFieldShouldReturn(textField: UITextField!) -> Bool 
    { 
    textField.resignFirstResponder() 
    return true; 
    } 
} 
+1

Попробуйте поместить вновь созданный делегат в «сильную» переменную класса. Возможно, свойство «присваивать» поля делегата вызывает его освобождение сразу после его создания. –

ответ

7

Примечание Декларация о delegate:

unowned(unsafe) var delegate: UITextFieldDelegate? 

MyTextFieldDelegate() создан, назначен delegate , а затем освобождается, когда возвращается createUI(). Он освобождается ARC, потому что ничто не владеет им. Проблема, с которой вы столкнулись, именно то, о чем предупреждает unsafe.

Вам необходимо создать ссылку на ваш пример MyTextFieldDelegate. Вы также должны гарантировать, что делегат не будет освобожден до тех пор, пока текстовое поле не будет освобождено.

Обратите внимание на разницу между этим поведением и weak. Если делегат был weak вместо unowned(unsafe), то он стал бы nil и никогда не будет вызван, вместо того, чтобы сбой при его вызове.

+1

Спасибо за то, что все мои годы Java заставили меня воспринимать управление памятью как должное ... –

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