属性修饰符
属性修饰符
1.线程安全的
atomic、nonatomic
atomic: 原子性的,线程安全的,在OS中用的较多,有性能消耗,iOS中基本都是使用nonatomic,会在setter、getter方法中加锁,但是在其他地方并没有加锁,所以并不是真正的线程安全
nonatomic:非原子性,直接访问内存中的地址,不会判断是否有其他线程正在修改值,没有加锁解锁的操作,所以会比atomic性能高
如何真正线程安全的访问共有资源(加锁的8种方式)
2.访问权限的
readonly、readwrite
readonly 只希望外界读取,不希望修改的时候使用;但是外部其实还是可以通过KVC的方式进行值修改,避免这种情况的话可以实现类方法,+ (BOOL)accessInstanceVariablesDirectly 使其返回 NO,这时如果还要修改 readonly 修饰的属性,就会crash
readwrite 属性默认的就是可读写,系统会自动生成setter、getter方法
3.内存管理(ARC)
assign、weak、unsafe_unretained、strong、retain、copy、
3.1 assign 非持有关系,可以修饰
3.2 weak 非持有关系
3.3 unsafe_unretained
3.4 strong
3.5 retain
3.6 copy
3.6.1 大多数用于对 NSString、NSDictionary、NSArray对象的修饰,为什么这三类要使用copy呢?首先要明白子类可以给赋值给父类,可变类是不可变类的子类(对NSString、NSDictionary、NSArray这三类来说); self.name=valueStr, 使用copy进行深拷贝得到新的对象,赋值后和原来的对象没有关系了;如果使用的是strong,valueStr是可变类型时,当valueStr进行添加删除操作等的时候, self.name也会跟着被改变,这种情况大多数不是我们想要的,所以使用copy。copy修饰后得到的变量是不可变的,因为实现了 NSCopying协议 -(id)copyWithZone 方法,得到的就是不可变变量,
3.6.2 当然也可以修饰 block, 为什么block中一般要使用copy呢?MRC环境下
(1)block访问外部局部变量,block存放在栈里面。
(2)只要block访问整个app都存在的变量,那么肯定是在全局区。
(3)不能使用retain引用block,因为block不在堆区里面,只有使用copy才会把block放在堆区里面。
ARC环境下
(1)只要block访问外部局部变量,block就会存放在堆区。
(2)可以使用strong去引用,因为本身就已经存放在堆区了。
(3)也可以使用copy进行修饰,但是strong性能更好。
如何自己实现weak
4.指定方法名称
setter =
getter =
5.是否为空
nonnull、nullable、null_resettable、null_unspecified
iOS9 以后才出现的几个修饰词,一方面是为了和swift的可选型、必选型做对接,另外一方面是为了提高代码规范,,对一些空值的情况作处理,提示使用的人应该传什么样的值,提高代码的健壮性。
声明临时变量内存修饰符
__strong, __weak, __unsafe_unretained, __autoreleasing,__block,