运行时应用场景

2016-06-14  本文已影响205人  英雄出少年
@interface NSObject (TGTest)
@property (nonatomic, strong) NSString* test;
//这样写会报错
@end
#import "NSObject+ TGTest.h"
#import <objc/runtime.h>
@implementation NSObject (TGTest)

- (void)setTest:(NSString*)test{ 
//将属性同对象关联
 objc_setAssociatedObject(self,@selector(setTest), test, OBJC_ASSOCIATION_COPY_NONATOMIC);}

- (NSString*)test{ 
//对出 key 关联的对象属性 return objc_getAssociatedObject(self, _cmd);}

@end

_cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例

static char kExtendVarKey; // 键名
- (void)someCategoryMethod
{
    NSString *extendVar = objc_getAssociatedObject(self, &kExtendVarKey);
    if(!extendVar){
        extendVar = @"someText";
        objc_setAssociatedObject(self, &kExtendVarKey, extendVar, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
}

** 使用_cmd可以直接使用该@selector的名称,即someCategoryMethod,并且能保证改名称不重复 **


- (void)someCategoryMethod
{
    NSString *extendVar = objc_getAssociatedObject(self, _cmd);
    if(!extendVar){
        extendVar = @"someText";
        objc_setAssociatedObject(self, _cmd, extendVar, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
}
+ (instancetype)itemWithDict:(NSDictionary *)dict
{
//    KVC做法: 遍历字典里面的所有key去模型中找,找到就赋值,找不到就会报错,模型作为key,不能为空
  TGItem *item =  [[self alloc] init];  
  [item setValuesForKeysWithDictionary:dict];
    return item;
}

- (void)setValue:(id)value forKey:(NSString *)key
{
    if ([key isEqualToString:@"id"]) {
        
        [self setValue:value forKeyPath:@"ID"];
        
    }else{
        [super setValue:value forKey:key];
    }
    
}

运行时

+ (instancetype)itemWithDict:(NSDictionary *)dict
{
    XMGHtmlItem *item = [XMGHtmlItem objcWithDict:dict mapDict:@{@"ID":@"id"}];
    
    // 遍历模型中属性名去字典中查找,如果找到就赋值,
    
    return item;
}


+ (instancetype)objcWithDict:(NSDictionary *)dict mapDict:(NSDictionary *)mapDict
{
    id objc = [[self alloc] init];
    // 遍历模型中属性
    unsigned int count = 0;
    Ivar *ivars = class_copyIvarList(self, &count);
    for (int i = 0 ; i < count; i++) {
        Ivar ivar = ivars[i];
        // 属性名称
        NSString *ivarName = @(ivar_getName(ivar));
        ivarName = [ivarName substringFromIndex:1];
        id value = dict[ivarName];
        // 需要由外界通知内部,模型中属性名对应字典里面的哪个key
        // ID -> id
        if (value == nil) {
            if (mapDict) {
            NSString *keyName = mapDict[ivarName]; 
            value = dict[keyName];
            }
        }
            [objc setValue:value forKeyPath:ivarName];   
    }
    return objc;
}
@implementation UIImage (Extension)
/**
 *  只要分类被装载到内存中,就会调用1次
 */
+ (void)load
{
    Method otherMehtod = class_getClassMethod(self, @selector(imageWithName:));
    Method originMehtod = class_getClassMethod(self, @selector(imageNamed:));
    // 交换2个方法的实现
    method_exchangeImplementations(otherMehtod, originMehtod);
}

+ (UIImage *)imageWithName:(NSString *)name
{
    BOOL iOS7 = [[UIDevice currentDevice].systemVersion floatValue] >= 7.0;
    UIImage *image = nil;
    if (iOS7) {
        NSString *newName = [name stringByAppendingString:@"_os7"];
        image = [UIImage imageWithName:newName];
    }
    
    if (image == nil) {
        image = [UIImage imageWithName:name];
    }
    return image;
}


@end

上一篇 下一篇

猜你喜欢

热点阅读