第一个最重要的问题:为什么要有@property?
在没有@property之前,定义实例变量是这样:
@interface Person : NSObject {
@public
NSString *name;
@private
int age;
}
@end
然后在.h文件,声明setter和getter方法(setter和getter统称「accessors/存取器/访问器」),再在.m文件实现setter和getter,这样就可以封装起来,供其他类访问(取值、赋值)了。然而,即使不使用setter和getter,其他类也可以通过->来直接访问。
第二个问题:为什么要getter和setter呢?
1 在非ARC时代,可以在在getter和setter中进行内存管理 2 可以在getter和setter中添加额外的代码,实现特定的目的。比如赋值前(set)需要实现一些特定的内部计算,或者更新状态,缓存数据等等。 3 KVC和KVO都是基于此实现的
第三个问题:在早起版本中@property做了哪些事情?
1 在.h文件,用@property声明了属性——这只是帮我们在声明了getter和setter
2 还需要手动声明实例变量,后来,不需要为属性声明实例变量了,@synthesize会默认自动生成一个「下划线+属性名」的实例变量。
3 然后在.m文件,还要用@synthesize自动合成getter和setter的实现
第四个问题:现在如果面试官问你:如果我们写@property声明属性做了哪些事情?
1 .h: 声明了getter和setter方法 2 .h: 声明了实例变量(默认:下划线+属性名); 3 .m: 实现了getter和setter方法。
第五个问题:@property中()内的内容到底是什么呢?
这里大类可以分为三种类型:1 atomicity(原子性) 2 Access(存取特性) 3 Storage(内存管理特性)(管理对象的生命周期的)
第六个问题:atomic 一定是线程安全的吗?为什么我们看到大多数都是用nonatomic?
系统生成的 getter/setter 会保证 get、set 操作的完整性,不受其他线程影响。getter 还是能得到一个完好无损的对象(可以保证数据的完整性),但这个对象在多线程的情况下是不能确定的 atomic所说的线程安全只是保证了getter和setter存取方法的线程安全,并不能保证整个对象是线程安全的 因此,在多线程的环境下原子操作是非常必要的,否则有可能会引起错误的结果。但仅仅使用atomic并不会使得对象线程安全,我们还要为对象线程添加lock来确保线程的安全。在某个小项目中将所有的nonatomic删除,内存占用平均升高1M左右
@property (nonatomic) NSObject *nonatomicObj;
@property (atomic) NSObject *atomicObj;
- (void)setNonatomicObj:(NSObject *)nonatomicObj{
if (_nonatomicObj != nonatomicObj) {
[_nonatomicObj release];
_nonatomicObj = [nonatomicObj retain];
}
}
- (NSObject *)nonatomicObj{
return _nonatomicObj;
}
- (void)setAtomicObj:(NSObject *)atomicObj{
@synchronized(self) {
if (_atomicObj != atomicObj) {
[_atomicObj release];
_atomicObj = [atomicObj retain];
}
}
}
- (NSObject *)atomicObj{
@synchronized(self) {
return _atomicObj;
}
}