上一篇中我们定义属性使用copy,@property里面各种各样的配置到底是什么呢,我们该如何使用?其中atomic, nonatomic, readonly, readwrite, assign, retain, copy 这些关键字有什么用呢?我们看看下面的代码:
@interface Person:NSObject{
@property(nonatomic,copy) NSString *name; // 1
@property(nonatomic,retain) NSString *name; // 2
@property(nonatomic,retain,readwrite) NSString *name; // 3
@property(atomic,retain) NSString *name; // 4
@property(retain) NSString *name; // 5
@property(atomic,assign) NSInteger age; // 6
@property(atomic) NSInteger age; // 7
@property NSInteger age; // 8
@property(nonatomic,weak) id delegate; // 9
}
上面的代码中1,2,3 等价;4 ,5等价;6 ,7, 8 等价。也就是说atomic是默认行为,assign是默认行为,readwrite是默认行为。
OC属性会从三个方面定义实现属性:
- 线程安全
- 原子性/非原子性(atomic/nonatomic)
- 内存使用
- retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1
- assgin : 简单赋值,不更改索引计数
- copy : 建立一个索引计数为1的对象,然后释放旧对象
- 读写控制
- readonly : 表示这个属性是只读的,就是只生成getter方法,不会生成setter方法
- readwrite : 设置可供访问级别
那么这个时候问题来了,我们怎么选择要定义属性的所选的类型呢?
关于线程安全:
atomic/nonatomic,我们在使用的时候结合实际使用场景,通常为了性能的考虑使用 nonatomic,对于有一些属性我们要保证其线程安全那么就可以使用atomic,保证线程安全仅仅靠atomic是无法保证,还得考虑线程同步和互斥机制。
内存使用:
assign : 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等);
copy: NSString使用,下面代码看我们定义name具体实现:
-(void) setName:(NSString *)name{
if (_name != name) {
[_name release];
_name = [name copy];
}
}
retain: 对其他NSObject和其子类
读写控制:
readonly:此标记说明属性是只读的。比如系统定义的一些UI控件的某些属性为只读。虽然在定时标注为只读(只帮我们生成getter方法),但是我们也可以自己实现setter方法如下:
@interface Person : NSObject{
@property(nonatomic,copy,readonly) NSString *name;
-(void) setName:(NSString*)newName;
readwrite:此属性是系统默认,根据实际场景使用即可。
通常我们还会看到在定义属性的时候有strong和weak,那么这又是什么呢?
其实我们现在开发大多都是ARC(自动内存管理)这个时候属性定义strong相当于retain,而weak相当于assgin。我们来看下面的代码:
@interface Person:NSObject{
@property(nonatomic,strong) NSString *name;
@property(nonatomic,weak) id delegate;
}
之后我们详细说明iOS内存管理。其实还有属性的命名空间和作用域,属性的赋值:点语法赋值,KVC赋值等。
以上内容如果有错误的地方请大家留言或者联系微博