私有属性
在类扩展中的私有属性,只有类自己改,其他类在外部是不能修改的。
@interface Person ()
// 昵称;私有属性
@property (nonatomic, copy) NSString *nickname;
@end
- (void)viewDidLoad {
[super viewDidLoad];
// 初始化
self.person = [[Person alloc] init];
// 公共属性,可以在外部设置
self.person.age = 30;
self.person.name = @"小明";
// nickName是私有属性,无法设置
NSLog(@"%@", self.person);
}
输出内容如下:nickName的值为默认甚至的@"nil"
2021-02-23 19:07:41.783388+0800 RuntimeDemo[7583:522583] <Person: 0x60000262a660> {
nickname = nil;
name = 小明;
age = 30;
}
如何修改私有属性
属性其实是成员变量+set/get
;所以直接修改成员就可以改变属性的值。
runtime
中的函数class_copyIvarList
可以得到对象的成员变量。
// 修改属性值
- (IBAction)modifyButtonTouched:(id)sender {
NSLog(@"修改前:");
NSLog(@"%@", self.person);
unsigned int count = 0;
Ivar *ivar = class_copyIvarList(self.person.class, &count);
for (int i = 0; i < count; i++) {
Ivar tempIvar = ivar[I];
const char *varName = ivar_getName(tempIvar);
NSString *varNameString = [NSString stringWithUTF8String:varName];
// 名字;公共属性,可以修改
if ([varNameString isEqualToString:@"_name"]) {
object_setIvar(self.person, tempIvar, @"小明的新名字");
}
// 年龄;值类型;感觉上修改成功了;但是NSNumber的打印(就是Description)不正常;
// if ([varNameString isEqualToString:@"_age"]) {
// object_setIvar(self.person, tempIvar, @11);
// }
// 昵称是私有属性,也能修改
if ([varNameString isEqualToString:@"_nickname"]) {
object_setIvar(self.person, tempIvar, @"小明的昵称");
}
}
// 释放
free(ivar);
NSLog(@"修改后:");
NSLog(@"%@", self.person);
}
测试一下
2021-02-23 19:11:21.785616+0800 RuntimeDemo[7583:522583] 修改前:
2021-02-23 19:11:21.786100+0800 RuntimeDemo[7583:522583] <Person: 0x60000262a660> {
nickname = nil;
name = 小明;
age = 30;
}
2021-02-23 19:11:21.786434+0800 RuntimeDemo[7583:522583] 修改后:
2021-02-23 19:11:21.786871+0800 RuntimeDemo[7583:522583] <Person: 0x60000262a660> {
nickname = 小明的昵称;
name = 小明的新名字;
age = 30;
}
从打印信息可以看出,不管是公有属性name
,还是私有属性nickname
,在runtime
这一层都是一样的,没有任何区别。
问题
对于值类型,比如这里的age,应该能够修改成功,但是打印出来的内容不正常
2021-02-23 19:14:52.547713+0800 RuntimeDemo[7609:526593] 修改前:
2021-02-23 19:14:52.547986+0800 RuntimeDemo[7609:526593] <Person: 0x60000185c920> {
nickname = nil;
name = 小明;
age = 30;
}
2021-02-23 19:14:52.548178+0800 RuntimeDemo[7609:526593] 修改后:
2021-02-23 19:14:52.548427+0800 RuntimeDemo[7609:526593] <Person: 0x60000185c920> {
nickname = 小明的昵称;
name = 小明的新名字;
age = -4059584697397031632;
}
代码中,明明设置的是object_setIvar(self.person, tempIvar, @11);
打印出来的却是age = -4059584697397031632;
推测
应该修改成功了,只不过值类型在设置的时候需要包装成NSNumber类型,所以修改是对的,但是打印的内容由问题。
可以断点看一下:
但是显示是不正常的:
image.png
网友评论