runtime小结黑魔法

(一)拦截交换系统设置图片的方法

#import
<UIKit/UIKit.h> @interface UIImage (MyImage) + (UIImage *)theNewImageName:(NSString *)name; @end
#import "UIImage+MyImage.h"
#import <objc/runtime.h>

@implementation UIImage (MyImage)

+ (void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //交换设置图片的方法
#pragma mark ---如果需要交换的方法是 “-”实例方法 就用 class_getInstanceMethod, ,如果是“+”类方法 就用class_getClassMethod
        Method originMethod = class_getClassMethod(self, @selector(imageNamed:));
        Method customMethod = class_getClassMethod(self, @selector(theNewImageName:));
        method_exchangeImplementations(originMethod, customMethod);

    });
}

+ (UIImage *)theNewImageName:(NSString *)name
{
    NSString *theName = [NSString stringWithFormat:@"new_%@",name];
    return [UIImage theNewImageName:theName];
}




@end

(二)给系统类添加属性

#import <Foundation/Foundation.h>

@interface NSDictionary (MyDictionary)

//给字典类增加属性
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *gender;


@end
#import "NSDictionary+MyDictionary.h"
#import <objc/runtime.h>

@implementation NSDictionary (MyDictionary)

/**
 在延展里面都
 *  object:要关联的对象
 key:要关联的属性的key值
 value:要关联的属性
 polocy:是枚举类型
 enum {
 OBJC_ASSOCIATION_ASSIGN = 0, 所修饰的属性对象是弱引用的
 OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, 强引用,非线程安全
 OBJC_ASSOCIATION_COPY_NONATOMIC = 3, 指定相关的复制对象,非线程安全
 OBJC_ASSOCIATION_RETAIN = 01401, 指定关联的对象的强引用,线程安全 默认atomic
 OBJC_ASSOCIATION_COPY = 01403 指定相关的复制对象 ,默认是atomic
 };
 */

- (void)setName:(NSString *)name
{
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name
{
  return objc_getAssociatedObject(self, @selector(name));
}

- (void)setGender:(NSString *)gender
{
    objc_setAssociatedObject(self, @selector(gender), gender, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)gender
{
    return objc_getAssociatedObject(self, @selector(gender));
}



@end

(三)使用RunTime给类属性归档

#import <Foundation/Foundation.h>

@interface Person : NSObject

- (void)eat;
- (void)drink;

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *gender;
@property (nonatomic, assign) NSInteger age;

@end
//归档
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    unsigned int count = 0;
    //1.获得变量列表数组
    Ivar *ivarList = class_copyIvarList([self class], &count);
    //2.循环
    for (int i = 0; i < count; i++) {
        //3.获取变量名
        Ivar ivar = ivarList[i];
        //4.将c语言字符串转换成 oc字符串
        NSString *ivarString = [NSString stringWithUTF8String:ivar_getName(ivar)];
        //5.归档
        [aCoder encodeObject:[self valueForKey:ivarString] forKey:ivarString];
    }

}

//反归档
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if (self) {
        unsigned int count = 0;
        Ivar *ivarList = class_copyIvarList([self class], &count);
        for (int i = 0; i < count; i++) {
            Ivar ivar = ivarList[i];
            NSString *ivarString = [NSString stringWithUTF8String:ivar_getName(ivar)];
            //反归档
            [self setValue:[aDecoder decodeObjectForKey:ivarString] forKey:ivarString];
        }
    }
    return self;
}
原文地址:https://www.cnblogs.com/arenouba/p/5462627.html