iOS 进阶 01--对象与方法的本质
2019-02-26 本文已影响0人
尤先森
对象与方法的本质
- Objective-C 对象
Class
的本质是结构体。
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class
const char *name
long version
long info
long instance_size
struct objc_ivar_list *ivars
struct objc_method_list **methodLists
struct objc_cache *cache
struct objc_protocol_list *protocols
#endif
} OBJC2_UNAVAILABLE;
- Objective-C 方法
Method
的本质是发送消息,任何的方法的调用都会编译成消息。
消息的组成:
objc_msgSend(id self, SEL _cmd, ...)
消息接受者,消息编号,参数 (消息体)
objc_msgSend(id self, SEL _cmd, ...)
消息的组成由 id self,SEL _cmd 以及后续的参数其中,
id self 可以理解为调用方法的对象,消息接受者,即下文中的 "s"。
SEL _cmd 为方法名,传入类似sel_registerName("MethodName"),即下文中的"[s walk];"方法。
若方法中需要传入参数,就在后面拼接,即下文中的 "[s say:]"方法。
获取SEL的三种方法:
1. Runtime提供的 sel_registerName
2. Objective-C编译器提供的 @selector()
3. NSObject提供的 NSSelectorFromString()
SEL与IMP(implementation)的关系:
sel_registerName("MethodName")为方法编号,通过方法编号找到方法对应的IMP是函数实现的指针,
最后直接调用函数。
比喻:通过书页(SEL) 找到该页的具体内容 (IMP)
- 实例方法调用
Student *s = [Student new];
[s walk];
objc_msgSend(s, @selector(walk));
//带参数
[s say:@"Hello World"];
objc_msgSend(s, sel_registerName("say:"), "Hello World");
- 类方法调用
[Student run];
objc_msgSend(objc_getClass("Student"), sel_registerName("run"));
//带参数
[Student say:@"Hello World"];
objc_msgSend(objc_getClass("Student"), sel_registerName("say:"), "Hello World");
- 如何给父类发消息
Student *s = [Student new];
// 向父类发消息(对象方法)
struct objc_super superClass;
superClass.receiver = s; //确定这个消息发送的对象,即发送给s的父类
superClass.super_class = class_getSuperclass([s class]);
objc_msgSendSuper(& superClass, sel_registerName("walk"));
//向父类发消息(类方法)
struct objc_super superClass;
superClass.receiver = [s class];
superClass.super_class = class_getSuperclass(object_getClass([s class]));
objc_msgSendSuper(& superClass, sel_registerName("run"));
//带参数
objc_msgSendSuper(& superClass, sel_registerName("say:"),@"Hello World");
- 问答
问:对象方法和类方法存在哪?
答:元类
问:“类方法”在元类中是以什么样的姿态存在
答:实例方法。因为:对象在类中是实例,类在元类中也是对象、实例,参考:isa走位图