在OC的内存管理中,如果忘记释放OC对象,很有可能就造成内存泄露。为了避免忘记释放内存,我们通常在setter方法中释放类属性中的OC对象,这也使得代码过于麻烦。好在@property
的参数解决了这个问题。
正文:
一. 首先,@property都有哪些常用参数
除了这些,还有getter和setter等,将在下面做讲解。
二. 详细讲解
1. readwrite / readonly
系统默认值为:readwrite。
@property (readwrite) int age;
等价于:
@property int age;
等价于:
- (void) setAge : int newAge {
_age = newAge;
}
- (int) getAge {
return _age;
}
如果设置属性只读:
@property (readonly) int age;
等价于:
- (int) getAge {
return _age;
}
2. assign / retain / copy
这对参数主要用于OC对象释放的时候。assign是在setter时,直接赋值,没有额外操作,而retain则需要先释放旧的对象,再赋值。 对基本类型(int char …)进行retain是错误的。
@property (assign) classA *a;
等价于:
@property classA *a;
等价于:
- (void) setA : (classA *) newA {
_a = newA;
}
- (classA *) getA {
return _a;
}
但是这种实现方式,很有可能造成内存泄露(对象没有完全释放)这种问题。oc也给我们提供了一种安全的setter方式,就是使用retain参数,这样也避免了自己敲在setter中释放内存这段代码。
@property (retain) classA *a;
等价于:
- (void) setA : (classA *) newA {
if (_a != newA) {
[_a release];
_a = newA;
}
}
- (classA *) getA {
return _a;
}
所以在声明OC对象的时候,更建议直接使用retain参数,避免自己重复在setter中写释放内存的代码。
copy参数会在setter中copy对象,与retain类似
@property (copy) classA *a;
等价于:
- (void) setA : classA *newA {
if (_a != newA) {
[_a release];
_a = [newA copy]
}
}
3. atomic / nonatomic
这对参数用于线程是否安全。atomic线程安全,nonatomic线程不安全。
虽然线程安全可以防止出现死锁,但是效率却降低了。所以,在开发过程中,用得最多的还是nonatomic参数。
@property classA *a;
等价于
@property (atomic) classA *a;
等价于:
- (classA *) getA {
[_a retain];
return [_a autorelease];
}
线程不安全的情况:
@property (nonatomic) classA *a;
等价于:
- (classA *) getA {
return _a;
}