【问题标题】:UITextFieldDelegate not working if instantiated in viewDidLoad如果在 viewDidLoad 中实例化 UITextFieldDelegate 不起作用
【发布时间】:2017-11-01 20:49:05
【问题描述】:

如果我在 ViewController 中实例化委托,一切正常,委托被正确调用:

class ViewController: UIViewController {

    @IBOutlet weak var topText: UITextField
    let topDelegate = UpperTextDelegate()

    override func viewDidLoad() {
        topText.delegate = topDelegate
    }
    // GOOD, DELEGATE METHODS ARE GETTING CALLED AS EXPECTED

如果我在 viewDidLoad 方法内实例化委托,事情就会中断,委托方法不会被调用。

class ViewController: UIViewController {

    @IBOutlet weak var topText: UITextField

    override func viewDidLoad() {
        topText.delegate = UpperTextDelegate()
    }
    // BAD, DELEGATE METHODS ARE NOT GETTING CALLED :-(

请问这是怎么回事?

---------

这是代表:

import UIKit

class UpperTextDelegate: NSObject, UITextFieldDelegate {

    func textFieldDidBeginEditing(_ textField: UITextField) {
        textField.text = ""
    }   
}

【问题讨论】:

  • UpperTextDelegate()的放代码
  • 您确定在设置委托后调用了委托方法吗?如果在 ViewController 的viewDidLoad 之前调用,则不会调用UpperTextDelegate 的委托方法。

标签: ios swift


【解决方案1】:

第二个代码不起作用,因为您没有强烈引用您的委托。您只需实例化一个 UpperTextDelegate 对象并将其分配给一个弱属性。它会立即释放。

UITextField 的delegate 属性很弱,因为否则你总是会得到一个保留周期。 (您的 ViewController 持有对其视图的引用 -> 它持有对其子视图 (UITextField) 的引用 -> 将持有对其委托即您的 ViewController 的引用。)

如果您在类中定义变量(必须是可选的,或者您必须在 init() 中为其分配值),然后您在 viewDidLoad 中为其分配值,您的代码将起作用。

我建议在 iOS 中搜索 ARC (Automatic Reference Counting)delegation pattern

【讨论】:

    【解决方案2】:

    您的代码是否正确构建,因为我认为弱属性必须是可选的(毕竟它可能设置为 nil)。

    在任何情况下,弱声明都是导致问题的原因。

    当你声明一个属性weak时,类不会保留对它的引用,因此它只有在对象本身的范围有效时才有效。在您的第一个示例中,“topDelegate”是在类本身中定义的,因此只要类存在,它就在范围内。在第二个示例中,“topDelegate”是在 viewDidLoad 方法中定义的,并且只要该方法存在,它就在范围内,这就是为什么在 viewDidLoad 完成后不调用任何委托方法的原因。

    某些东西必须保留“topDelegate”,因此您必须在类中定义它(在这种情况下,为什么不直接删除弱引用)或者其他东西应该保留它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-06
      • 2016-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      相关资源
      最近更新 更多