Nick Holt
Nick Holt

Reputation: 34301

Implementing UITextFieldDelegate in a separate class

I want to implement UITextFieldDelegate in a class separate from the UIViewController but when I do I get a EXC_BAD_ACCESS exception at runtime.

So why does this work:

class MyViewController : UIViewController, UITextFieldDelegate
{
  ...

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

    ...
  }

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

But this doesn't:

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;
  }
}

Upvotes: 7

Views: 1332

Answers (1)

Aaron Brager
Aaron Brager

Reputation: 66242

Note the declaration of delegate:

unowned(unsafe) var delegate: UITextFieldDelegate?

MyTextFieldDelegate() is created, assigned to delegate, and then deallocated when createUI() returns. It is deallocated by ARC because nothing owns it. The problem you are experiencing is exactly what unsafe is warning you about.

You need to create a strong reference to your MyTextFieldDelegate instance. You also need to guarantee that the delegate is not deallocated until after the text field is deallocated.

Note the difference between this behavior and weak. If the delegate were weak instead of unowned(unsafe), then it would become nil and never get called, instead of crashing when it's called.

Upvotes: 7

Related Questions