规则
在ARC有效的情况下编译源代码,必须遵守一定的规则。下面就是具体的ARC的规则。
●不能使用retain/release/retainCount/autorelease
●不能使用NSAllocateObjectNSDeallocateObject
●须遵守内存管理的方法命名规则
●不要显式调用dealloc
●使用@autoreleasepool块替代NSAutoreleasePool
●不能使用区域(NSZone)
●对象型变量不能作为C语言结构体( struct/union)的成员●显式转换“id"和“void *”
以上内容出自《iOS与OS X多线程和内存管理》
属性(property)
日常我们经常看见下面的写法,那么它到底是什么,做了那些事情呢
@property (nonatomic,copy)NSString *name;
属性用于封装对象中的数据,iOS开发中最常用最方便的变量声明方式,允许我们用点语法来访问对象的实例变量。上面一行代码其实干了三件事:在编译阶段,编译器会自动给对象添加一个实例变量_name和它的存取方法- (void)setName:(NSString *)name和- (NSString *)name。
中间的部分很多资料叫法都不一样,但是不必纠结这个,就认为它是property为变量声明的属性吧。属性在类别上可分为三种,原子属性,读写属性和内存管理属性。
原子性:nonatomic,atomic
其实我们用到的一般都是nonatomic,因为atomic属性下由编译器合成的set方法通过同步锁的机制保证其原子性存取方法是线程安全的,但是我们依旧可以绕过set方法来进行赋值,并且这种情况下还有一定的性能开销,所以基本不用atomic。
读写权限:readonly,readwrite
readonly修饰属性时,编译器只会自动合成get方法,而readwrite修饰属性时,编译器会自动合成set和get方法。
内存管理属性
因为之前有总结过所有权修饰符,所以可以通过下面的表格来看一下属性声明的属性与所有权修饰的关系
这里有两个需要再说一下,别的可以参考所有权修饰符来理解,
assign:assign只可以用来修饰基本数据类型,该方式会对象直接赋值而不会进行retain操作。
copy:表⽰重新建立一个新的计数为1的对象,然后释放掉旧的值。NSString、NSArray、NSDictionary 等经常使用 copy 关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,为确保对象中的属性值不会无意间变动,应该在设置新属性值时拷贝一份。而NSMutableString、NSMutableArray、NSMutableDictionary 则往往使用 strong 关键字更为妥当。
另外就是同事问过retain和strong区别,其实二者区别主要体现再修饰block,strong修饰block,相当于copy,此时block是放在堆上的,生命周期不回随函数周期结束而出栈,但是retain修饰的block是存放在栈上,block会有以前被释放的风险。至于block以后再总结。