UIImage叫做方法调用者,也叫做担当者。imageNamed:是方法名,也叫选择子。选择子与参数合起来叫做“消息”。在OC中,假如向某对象传递信息,那就会利用动态绑定机制来决定需要的方法。为什么OC是真正的动态语言呢?由于对象收到信息之后,究竟该调用哪个方法则完全于运行期决定,甚至可以在程序运行时改变。编译器看到"消息"时,会将它换为一条标准的 C 语言函数调用,所调用的函数乃是消息传递机制中的核心函数,叫做 objc_msgSend。
动态绑定:
动态绑定机制是面向对象编程中的一个重要特性,它允许在运行时确定对象的类型并调用其关联的方法。这种机制允许我们编写更加灵活和可扩展的代码,由于我们可以在代码运行时根据对象的实际类型来决定执行哪些操作。
在动态绑定机制中,方法调用不是在编译时确定的,而是在运行时确定的。这意味着,你可以在程序运行的过程中改变对象的类别大概改变对象响应的方法。比方,假如你有一个 Animal 类型的对象,这个对象可能是 Dog 类型,也可能是 Cat 类型,具体是什么类型会在运行时确定。然后,当你调用这个 Animal 对象的 makeSound 方法时,假如它是一个 Dog 对象,就会执行 Dog 的 makeSound 方法,假如它是一个 Cat 对象,就会执行 Cat 的 makeSound 方法。这个过程就是动态绑定。
动态绑定机制大大加强了代码的灵活性,使得我们可以编写出更加通用的代码。比方,我们可以编写一段处理 Animal 对象的代码,而不用关心这个 Animal 对象到底是 Dog 还是 Cat,具体的处理逻辑会在运行时通过动态绑定机制确定。这种方式使得我们的代码更加易于扩展,由于我们可以随时添加新的 Animal 子类,而不需要改变处理 Animal 对象的代码。
OC中的消息表达式:
id returnValue = [someObject messageName: parameter];
复制代码
这里,someObject叫做接收者(receiver),messageName:叫做选择子(selector),选择子和参数合起来称为“消息”。编译器看到此消息后,将其转换为一条标准的C语言函数调用,所调用的函数乃是消息传递机制中的核心函数叫做objc_msgSend,编译器看到上述这条消息会转换成一条标准的 C 语言函数调用:
id returnValue = objc_msgSend(someObject, @selector(messageName:), parameter);
选择器是在编译阶段由编译器天生的。编译器会根据方法名(包括参数序列)天生一个唯一的 ID,这个 ID 就是 SEL 类型的。这意味着,只要方法的名字(包括参数序列)相同,无论是在父类还是子类中,他们的选择器就是相同的。
比方我如今有一个父类class1,其中有两个方法eat和eat:,有一个class2作为class1的子类,该子类中有个与父类同名的eat:方法,分别获取三个方法的选择器,会发现只要是名称相同,哪怕是在父类和子类中的方法,选择器地址相同: