gpt4 book ai didi

ios - 当我在 Swift 中将对象的委托(delegate)设置为 "self"时,编译器在做什么?

转载 作者:可可西里 更新时间:2023-11-01 00:21:31 27 4
gpt4 key购买 nike

在我的代码中我有 UIViewController实现 UITextFieldDelegate , 和 UIPickerViewDelegate .

textField 的委托(delegate)和 pickerView通过 textField.delegate = self 分配和 pickerView.delegate = self分别。

我理解两者的协议(protocol)状态只接受与其委托(delegate)匹配的类型,但我不确定编译器如何区分这两种类型的 UIPickerViewDelegateUITextFieldDelegate因为类是两个协议(protocol)都可以作为自身传递。

当我设置时编译器到底在做什么 textField.delegate pickerView.delegate self ? 编译器似乎很聪明,可以解决这个问题,但我很想知道幕后发生了什么。

例如:

class TextFieldViewController: UIViewController, UITextFieldDelegate,  UIPickerViewDelegate {

@IBOutlet weak var textField: UITextField!
@IBOutlet weak var pickerView: UIPickerView!

override func viewDidLoad() {
super.viewDidLoad()

pickerView.delegate = self
textField.delegate = self
}

}

最佳答案

What exactly is the compiler doing when I set textField.delegate

这个问题有两种答案:一种针对纯 Swift 类型,另一种针对 Objective-C 协议(protocol)。

由于您的示例是关于 Objective-C 的(因为 UITextFieldDelegate 是一个 Objective-C 协议(protocol)),所以我将首先回答这个问题。

Objective-C @protocol

编译器的工作不仅是生成代码,还检查正确性。它通过确保分配给 UITextFielddelegate 属性的对象的静态类型与声明匹配来做到这一点。在这种情况下,如果 self 的类型不符合 UITextFieldDelegate,编译器会报错。

这叫做 static type safety并且是一个纯粹的编译时概念,不会影响代码或运行时。

在稍后阶段,编译器必须生成执行实际赋值的代码。在设置 objc 属性的情况下,它将查找 setter 名称(使用 setDelegate:)并使用此选择器发出 objc_msgSend 调用。

magic in this function是什么使得向任何对象发送任意消息成为可能。因为这是在运行时发生的(术语是“后期绑定(bind)”或“动态分派(dispatch)”),编译器的工作在此时完成。

当文本字段尝试回调委托(delegate)时,它使用相同的机制发送消息。它不需要知道委托(delegate)的类型,除了它是一个 Objective-C 对象。

当使用 @objc 实例时,对于 Objective-C 和 Swift 代码都是如此。

纯 Swift 协议(protocol)

当委托(delegate)是纯 Swift 协议(protocol)(不是从 NSObject 协议(protocol)派生的)时,一切都变了。由于您的问题不是专门针对此案例,因此我不会详细介绍。

在纯 Swift 中,没有后期绑定(bind):方法名称与其实现之间的联系是在编译时建立的(而在 Objective-C 中,这是在运行时发生的)。

由于假设的纯 Swift TextField 中的委托(delegate)属性必须有一种方法可以在委托(delegate)中找到协议(protocol)方法,因此编译器会为协议(protocol)和静态类型创建一个所谓的见证表并存储它连同实例。在委托(delegate)中调用方法时,编译器通过见证表路由调用以查找实际实现。在编译期间比在 Objective-C 情况下完成更多的工作。

如果您想了解更多有关 Swift 如何表示数据和调度方法的信息,请访问 2016 WWDC video其中有一些细节(这里是 the transcript )。

另外,我非常推荐深入研究 Swift ABI documentation .关于Existential Container Layout的部分描述了纯 Swift TextField 将如何存储其 delegate 属性。

关于ios - 当我在 Swift 中将对象的委托(delegate)设置为 "self"时,编译器在做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40685940/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com