要访问一个类的私有属性,很容易想到使用KVC,其实还有种方法就是利用runtime。但runtime有个短板在于,在ARC下,不支持对基本数据类型的变量进行修改。
示例:
新建Person类,声明name和age两个私有实例变量或property属性并初始化,重写description方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @interface Person() { NSString *_name; } @property (nonatomic, assign) NSInteger age; @end
@implementation Person -(instancetype)init { self = [super init]; if (self) { _name = @"郑郑"; _age = 17; } return self; }
-(NSString *)description { return [NSString stringWithFormat:@"niceGirl name=%@,age = %ld",_name,_age]; }
@end
|
使用KVC对Person的私有变量进行修改:
1 2 3 4 5 6 7 8 9
| _niceGirl = [[Person alloc] init];
[_niceGirl setValue:@"冰冰棒" forKey:@"name"]; [_niceGirl setValue:@18 forKey:@"age"]; NSLog(@"KVC修改后——%@",_niceGirl);
|
KVC支持对私有实例变量、属性进行修改,包括基本数据类型和Objective-C类型。
使用runtime对私有变量进行修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| unsigned int count = 0;
Ivar *members = class_copyIvarList([Person class], &count); for (int i = 0; i < count; i++) { Ivar ivar = members[i]; const char *memberName = ivar_getName(ivar); if (memberName) { NSString *ivarName = [NSString stringWithUTF8String:memberName]; if ([ivarName containsString:@"name"]) { object_setIvar(_niceGirl, ivar, @"小糊涂"); }
} } NSLog(@"runtime修改后——%@",_niceGirl);
|
注意:object_setIvar(id obj, Ivar ivar, id value)
方法不能实现对基本数据类型的修改,在ARC下Ivar object_setInstanceVariable(id obj, const char *name, void *value)
不可用,所以也不能实现对私有变量的修改。