如果我在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 = ""
}
}
答案 0 :(得分:2)
第二个代码不起作用,因为您没有强力引用您的代理人。您只需实例化一个UpperTextDelegate对象并将其分配给弱属性。它会立即释放。
UITextField的委托属性很弱,否则您将始终获得保留周期。 (您的ViewController保存对其视图的引用 - >它保存对其子视图(UITextField)的引用 - >它将保存对其作为ViewController的委托的引用。)
如果在类中定义变量(必须是可选的,或者必须在init()中为其赋值),然后在viewDidLoad中为其赋值,则代码将起作用。
我建议在iOS中谷歌 ARC(自动引用计数)和委派模式。
答案 1 :(得分:1)
你的代码是否构建正确,因为我认为弱属性必须是可选的(毕竟它可能设置为nil)。
在任何情况下,弱声明都是造成问题的原因。
当声明属性弱时,类不保留对它的引用,因此只有对象本身的范围有效时它才有效。在您的第一个示例中,'topDelegate'在类本身中定义,因此只要该类存在,它就在范围内。在第二个例子中,'topDelegate'是在viewDidLoad方法中定义的,只有在该方法存在的情况下它才在范围内,这就是为什么在viewDidLoad完成后没有调用委托方法的原因。
某些东西必须保留'topDelegate',所以要么你必须在类中定义它(在这种情况下为什么不只是删除弱引用)或者别的东西应该保留它。