[receiver message] 的理解
来源:互联网 发布:tomcat线程池优化 编辑:程序博客网 时间:2024/05/22 16:23
前言
[receiver message]不是一个简简单单的方法调用。因为这只是在编译阶段确定了要向接收者发送message这条消息,而receive将要如何响应这条消息,那就要看运行时发生的情况来决定了。
如果消息的接收者能够找到对应的selector,那么就相当于直接执行了接收者这个对象的特定方法;否则,消息要么被转发,或是临时向接收者动态添加这个selector对应的实现内容,要么就干脆玩完崩溃掉。
要更好的理解这个过程,先了解一下运行时
Objc Runtime
使得C具有了面向对象能力,在程序运行时创建,检查,修改类、对象和它们的方法。可以使用runtime的一系列方法实现。
/usr/include/objc/runtime.h
类的结构
struct objc_class { Class isa OBJC_ISA_AVAILABILITY;#if !__OBJC2__ Class super_class OBJC2_UNAVAILABLE; const char *name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; struct objc_method_list **methodLists OBJC2_UNAVAILABLE; struct objc_cache *cache OBJC2_UNAVAILABLE; struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;#endif} OBJC2_UNAVAILABLE;/* Use `Class` instead of `struct objc_class *` */
struct objc_class { Class isa OBJC_ISA_AVAILABILITY; //isa指针指向Meta Class,因为Objc的类的本身也是一个Object,为了处理这个关系,r untime就创造了Meta Class,当给类发送[NSObject alloc]这样消息时,实际上是把这个消息发给了Class Object #if !__OBJC2__ Class super_class OBJC2_UNAVAILABLE; // 父类 const char *name OBJC2_UNAVAILABLE; // 类名 long version OBJC2_UNAVAILABLE; // 类的版本信息,默认为0 long info OBJC2_UNAVAILABLE; // 类信息,供运行期使用的一些位标识 long instance_size OBJC2_UNAVAILABLE; // 该类的实例变量大小 struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 该类的成员变量链表 struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法定义的链表 struct objc_cache *cache OBJC2_UNAVAILABLE; // 方法缓存,对象接到一个消息会根据isa指针查找消息对象,这时会在method Lists中遍历,如果cache了,常用的方法调用时就能够提高调用的效率。 struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 协议链表 #endif } OBJC2_UNAVAILABLE;
OC中一个类的对象实例的数据结构
(/usr/include/objc/objc.h)
/// An opaque type that represents an Objective-C class.typedef struct objc_class *Class;/// Represents an instance of a class.struct objc_object { Class isa OBJC_ISA_AVAILABILITY;};/// A pointer to an instance of a class.typedef struct objc_object *id;#endif/// An opaque type that represents a method selector.typedef struct objc_selector *SEL;/// A pointer to the function of a method implementation. #if !OBJC_OLD_DISPATCH_PROTOTYPEStypedef void (*IMP)(void /* id, SEL, ... */ ); #elsetypedef id (*IMP)(id, SEL, ...); #endif
向object发送消息时,Runtime库会根据object的isa指针找到这个实例object所属于的类,然后在类的方法列表以及父类方法列表寻找对应的方法运行。id是一个objc_object结构类型的指针,这个类型的对象能够转换成任何一种对象。
objc_msgSend函数
消息发送步骤:
1、检测这个 selector 是不是要忽略的。比如 Mac OS X 开发,有了垃圾回收就不理会 retain,release 这些函数了。
2、检测这个 target 是不是 nil 对象。ObjC 的特性是允许对一个 nil 对象执行任何一个方法不会 Crash,因为会被忽略掉。
3、如果上面两个都过了,那就开始查找这个类的 IMP,先从 cache 里面找,完了找得到就跳到对应的函数去执行。
4、如果 cache 找不到就找一下方法分发表。
5、如果分发表找不到就到超类的分发表去找,一直找,直到找到NSObject类为止。
6、如果还找不到就要开始进入动态方法解析了。
后面还有:
动态方法解析resolveThisMethodDynamically
消息转发forwardingTargetForSelector
- [receiver message] 的理解
- Message Receiver
- go 类型方法 receiver的理解
- Handler、Looper、Message的理解
- 关于HANDLE_##MESSAGE , chHANDLE_DLGMSG宏的理解!!!!
- Message,MessageQueue,Looper,Handler的理解
- JVM(Java Message Service)的理解
- 关于android Handler Message Looper的理解
- Handler、HandlerThread、Message之间的关系理解
- android hanlder loop message的理解
- Handler,Looper,Message的深入理解
- Handler Looper Message MessageQueue的理解
- Handler,Looper,Message的理解与困惑
- 对于 Handler MessageQueue Message Looper的理解
- Android的Broadcast Receiver
- android的receiver优先级
- Receiver 的 log Tracing
- Broadcast Receiver 的使用
- 内核启动常见问题
- 最大最小元问题
- 用java为文件或文件夹中同一类型文件的开头或末尾处加上指定标示
- C++学习笔记 24
- Django分页
- [receiver message] 的理解
- 为人生自由
- Java内存模型以及gc算法
- 密码验证的正则表达式 (6-16位字母和数字组合)
- win7-MySQL数据库安装与配置详解
- Vue搭建
- AbstractQueueSynchronizer源码
- 模仿通讯录按字母分类显示,汉字,英文自动按英文字母分类显示,滑动时用气泡显示最上面的汉字首字母提示,右侧字母栏点击快速定位
- DispatcherServlet详解 ——跟开涛学SpringMVC