iOS 进阶 01--对象与方法的本质

2019-02-26  本文已影响0人  尤先森

对象与方法的本质

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;

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走位图

上一篇 下一篇

猜你喜欢

热点阅读