一、动态生成对象:

1
2
Class class = NSClassFromString(@"User");
id object = [[class alloc]init];

二、获取属性列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(NSMutableArray*)getPropertiesWithClass:(Class)cls{
// 获取当前类的所有属性
unsigned int count;// 记录属性个数
objc_property_t *properties = class_copyPropertyList(cls, &count);
// 遍历
NSMutableArray *mArray = [NSMutableArray array];
for (int i = 0; i < count; i++) {
// objc_property_t 属性类型
objc_property_t property = properties[i];
// 获取属性的名称 C语言字符串
const char *cName = property_getName(property);
// 转换为Objective C 字符串
NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
[mArray addObject:name];
}
return mArray.copy;
}

三、设置属性

1
2
3
4
5
6
 NSArray *properties = [self getPropertiesWithClass:class];
for (NSString* key in properties) {
if (dict[key]) {
[object setValue:dict[key] forKey:key];
}
}

四、替换方法 Method Swizzling

这里有两个方法,一个哭,一个笑,咱们做个小例子实现破涕为笑:

1
2
3
4
5
6
7
-(void)smile{
NSLog(@"smile");
}

-(void)cry{
NSLog(@"cry");
}

有几种替换方法:

  1. 使用method_exchangeImplementations直接替换两个方法。

    1
    2
    3
    4
    5
    Method old = class_getInstanceMethod(self.class, @selector(cry));
    Method new = class_getInstanceMethod(self.class, @selector(smile));

    method_exchangeImplementations(old, new);
    [self cry];
  2. 使用class_replaceMethod

    1
    2
    3
    4
    Method newMethod = class_getInstanceMethod(self.class, @selector(smile));
    class_replaceMethod(self.class, @selector(cry), method_getImplementation(newMethod), method_getTypeEncoding(newMethod));

    [self cry];
  3. 使用method_setImplementation

    1
    2
    3
    4
    5
    Method oldMethod = class_getInstanceMethod(self.class, @selector(cry));
    Method newMethod = class_getInstanceMethod(self.class, @selector(smile));

    method_setImplementation(oldMethod, method_getImplementation(newMethod));
    [self cry];

最后打印的结果都是smile的,是不是好神奇咧。
ps:如果需要替换的实现方法在整个程序的声明周期有效, 最好修改方法实现的操作放在+(void)load里,并在应用程序的一开始就调用执行。

想详细学hook的可以看这篇文章,美女写的:Objective-C的hook方案

另外,消息派发是runtime中非常重要的一个模块,以后有空再详细了解一下。