美文网首页
001 -Runtime使用

001 -Runtime使用

作者: 天雨流芳zhang | 来源:发表于2018-05-21 13:05 被阅读0次

    消息机制:

    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            Person *p= [[Person alloc]init];
            
        }
        return 0;
    }
    

    clang -rewrite-objc main.m手动编译OC文件

    int main(int argc, const char * argv[]) {
        /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 
            Person *p= ((Person *(*)(id, SEL))(void *)objc_msgSend)((id)((Person *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));
    
        }
        return 0;
    }
    

    C里面,基本数据类型的指针,作为参数传递。一般这个函数内部是为了修改外部基本变量的值。

    关于Runtime

    API:#import<objc/runtime.h>
    Ivar :成员变量
    Method:成员方法
    //copy creat new 代表着会在堆区域(malloc)开辟空间

        //查看一个类的所有属性列表
        Ivar *list = class_copyIvarList(Person.class, &count);
        free(list);
    

    自定义对象序列化:

    - (void)encodeWithCoder:(NSCoder *)aCoder{
        [aCoder encodeObject:_name forKey:@"name"];
        [aCoder encodeInteger:_age forKey:@"age"];
    }
    - (instancetype)initWithCoder:(NSCoder *)aDecoder{
        if (self = [super init]) {
            _age = [aDecoder decodeIntForKey:@"age"];
            _name = [aDecoder decodeObjectForKey:@"name"];
        }
        return self;
    }
    

    但是有一个弊端,就是类的属性特别多的情况下,我们需要手动写很多,那么有没有一种方法可以循环遍历属性。

    - (void)encodeWithCoder:(NSCoder *)aCoder
    {
    //C里面,基本数据类型的指针,作为参数传递。一般这个函数内部是为了修改外部基本变量的值。
        unsigned int count = 0;
    //copy creat new 代表着会在堆区域(malloc)开辟空间
        Ivar *list = class_copyIvarList(self.class, &count);
        for (int i = 0; i < count; i ++) {
            Ivar ivar = list[i];
            const char * name = ivar_getName(ivar);
            NSString *key = [NSString stringWithUTF8String:name];
            id value = [self valueForKey:key];
            [aCoder encodeObject:value forKey:key];
        }
    //栈平衡
        free(list);
        
    }
    - (instancetype)initWithCoder:(NSCoder *)aDecoder{
        unsigned int count = 0;
        if (self = [super init]) {
            Ivar *list = class_copyIvarList(self.class, &count);
            for (int i = 0; i < count; i ++) {
                NSString * key = [NSString stringWithUTF8String:ivar_getName(list[i])];
                //解档
               id value = [aDecoder decodeObjectForKey:key];
                //设值
                [self setValue:value forKey:key];
            }
            free(list);
        }
        return self;
        
    }
    

    发消息-->定位到方法(SEL地址)
    OC的方法表

    SEL编号-----IMP实现(指针)
    加载类到内存,程序刚启动的时候调用,调用在main函数之前(预加载)

    1.+(void)load{

    }

    初始化类,类第一次使用的时候调用一次

    2.+(void)initialize{

    }

    //OC方法中有两个隐藏的参数,一个是self,一个是cmd,这是怎么来的呢。以为OC方法的本质就是发消息。
    //objc_msgSend(p,@selector(eatWithObjc:),@"sugar");

    点击获取代码地址

    相关文章

      网友评论

          本文标题:001 -Runtime使用

          本文链接:https://www.haomeiwen.com/subject/dpaodftx.html