NSRuntime使用篇

使用总结
runtime开源代码

对象的关联:

    1. 设置关联值

void objc_setAssociatedObject(id object, const void *key, id value, objc _AssociationPolicy policy)
获取关联值
id objc_getAssociatedObject(id object, const void *key)

key和object保持一致

  • 2 获取关联值

id objc_getAssociatedObject(id object, const void *key)

序列化,json->model转换

  • 利用runtime进行coding操作,开发中常用的方案
/**归**/
   unsigned int outCount = 0;
   Ivar *ivars = class_copyIvarList([self class], &outCount);
   
   for (int i = 0; i < outCount; i++) {
       Ivar ivar = ivars[i];
       
       NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
       id value = [aDecoder decodeObjectForKey:key];
       [self setValue:value forKey:key];
   }
   free(ivars); 

/** 解*/
   unsigned int outCount = 0;
   Ivar *ivars = class_copyIvarList([self class], &outCount);
   for (int i = 0; i < outCount; i++) {
       Ivar ivar = ivars[i];
       
       NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
       id value = [self valueForKeyPath:key];
       [aCoder encodeObject:value forKey:key];
   }
   free(ivars);
  • model
/** 此处仅考虑单层模型*/
    id objc = [[self alloc] init];
    unsigned int count;
    
    Ivar *ivarList = class_copyIvarList(self, &count);
    for (int i = 0; i < count; i++) {
        Ivar ivar = ivarList[i];
        
        NSString *keyName = [NSString stringWithUTF8String:ivar_getName(ivar)];
        NSString *key = [keyName substringFromIndex:1];
        
        id value = dict[key];
        
        if (value) {
            [objc setValue:value forKey:key];
        }
    }
@implementation UIViewController (Tracking)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];

        SEL originalSelector = @selector(viewWillAppear:);
        SEL swizzledSelector = @selector(xxx_viewWillAppear:);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        // When swizzling a class method, use the following:
        // Class class = object_getClass((id)self);
        // ...
        // Method originalMethod = class_getClassMethod(class, originalSelector);
        // Method swizzledMethod = class_getClassMethod(class, swizzledSelector);

        BOOL didAddMethod =
            class_addMethod(class,
                originalSelector,
                method_getImplementation(swizzledMethod),
                method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) {
            class_replaceMethod(class,
                swizzledSelector,
                method_getImplementation(originalMethod),
                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

#pragma mark - Method Swizzling

- (void)xxx_viewWillAppear:(BOOL)animated {
    [self xxx_viewWillAppear:animated];
    NSLog(@"viewWillAppear: %@", self);
}
方法调用
  • 消息调用

objc_msgSend(receiver, selector)

工作原理:在所属类的方法列表中寻找对应的方法,成功匹配方法后会把结果缓存在“快递映射表”(hash)中,下次运行时候直接走映射表方法,快捷迅速。如果类方法中未匹配到对应方法会向上找父类的方法列表,最终找不到匹配的方法则进行消息转发机制

  • 消息转发机制

+(BOOL) resolveInstanceMethod:(SEL)selector;
-(id)forwardingTargetForSelector:(SEL)selector
-(void)forwardInvocation:(NSInvocation*)invocation

在转发中处理

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,814评论 0 9
  • 继上Runtime梳理(四) 通过前面的学习,我们了解到Objective-C的动态特性:Objective-C不...
    小名一峰阅读 782评论 0 3
  • 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的...
    lylaut阅读 831评论 0 4
  • 转载:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麦子阅读 774评论 0 2
  • 本文转载自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex阅读 801评论 0 1