iOS属性修饰词有非常多,网上的资料也是一抓一大把,就不一一阐述了。
这里主要讲的是属性下划线 _ 与成员变量的联系 、readOnly修饰符。
先上代码:
@interface Person : NSObject
{
// NSString *_age;
}
@property(nonatomic,strong) NSString *age;
@property(nonatomic,strong,readonly) NSString *name;
@end
1.属性下划线 _ 与成员变量的联系
我们之所以能在.m文件中可以直接的使用_age实例变量,原因就在于苹果将默认编译器从GCC转换为LLVM,从此不再需要为属性声明实例变量了。如果LLVM发现一个没有匹配实例变量的属性,它将自动创建一个以下划线开头的实例变量也就是_age。
2.由readOnly修饰符引发的一些思考:
用readOnly修饰符,系统不会自动生成setter方法。
思考一:如果外部要修改属性值的话,可以通过什么方式去修改?
答案是用KVC去修改
Person *model = [[Person alloc] init];
NSLog(@"Person name:%@",model.name);
[model setValue:@"Mr right" forKey:@"name"];
NSLog(@"Person name:%@",model.name);
输出:
2017-03-26 13:24:50.017421 [922:296049] Person name:(null)
2017-03-26 13:24:50.017522 [922:296049] Person name:Mr right
思考二:怎么防止外部去修改readOnly的属性值?
重写+ (BOOL)accessInstanceVariablesDirectly;
官方文档解释:Controls whether the NSKeyValueCoding methods may attempt to access instance variables directly. NSObject's implementation returns YES.
控制是否NSKeyValueCoding方法可以直接访问实例变量。NSObject的实现返回的是。
Person *model = [[Person alloc] init];
NSLog(@"Person name:%@,age:%@",model.name,model.age);
[model setValue:@"18" forKey:@"age"];
NSLog(@"Person age:%@",model.age);
[model setValue:@"Mr right" forKey:@"name"];
NSLog(@"Person name:%@",model.name);
输出:
2017-03-26 13:38:41.981745 [941:299100] Person name:(null),age:(null)
2017-03-26 13:38:41.981796 [941:299100] Person age:18
[model setValue:@"18" forKey:@"age"];可以正常赋值。
程序走到 [model setValue:@"Mr right" forKey:@"name"]; 会报错。
至此,本文章结束。