iOS属性关键字

对一个属性来说,无非俩个操作,读和取,对应的就是 get 和 set 方法;通俗一点讲,这些关键字是底层约定的一些标签,当你上层对声明的属性加上这些关键字时,底层会根据不同的标签,在 get 和 set 方法中,执行不同的代码。

readwrite、readonly

readwirte: 属性同时具有 set 和 get 方法。
readonly: 属性只具有 get 方法。
这俩关键字,就是和其词意一样 ,若只想类内部 set , 就声明 readonly。

strong、retain、weak、assign、copy

retain 、assign 是 MRC 时的关键字,到 ARC 时,换成了 strong 和 weak 。 属性默认是 MRC -- assign ;ARC -- object 是 strong,基本数据类型还是 assign 。 实际上 weak 和 assign 还是有一些不同的,strong 和 retain 几乎没什么区别,不过建议还是能用 retain 的地方尽量用 strong , 后面也不讲 retain 。 讲到这几个关键字,就必须说到引用计数(retainCount)和生命周期。

  • strong 和 weak
    strong 是每对这个属性引用一次,retainCount 就会+1,只能修饰 NSObject 对象,不能修饰基本数据类型。是 id 和 对象 的默认修饰符。
    weak 对属性引用时,retainCount 不变,只能修饰 NSObject 对象,不能修饰基本数据类型。 主要用于避免循环引用。

  • assign
    这个关键字,是默认关键字,可以修饰基本数据类型和 NSObject 对象。
    对这个关键字声明的属性操作时,retainCount 是一直不变的,一直为 1,只有主动调用 release 时 ,才会释放。
    但是为什么我们不会用assign去声明对象呢?
    这是因为 assign 修饰的对象(一般编译的时候会产生警告:Assigning retained object to unsafe property; object will be released after assignment)在释放之后,指针的地址还是存在的,也就是说指针并没有被置为nil,造成野指针。对象分配在堆上的某块内存,如果在后续的内存分配中,刚好分到了这块地址,程序就会 crash。
    为什么可以用assign修饰基本数据类型?
    因为基础数据类型是分配在栈上,栈的内存会由系统自己自动处理回收,不会造成野指针。

  • copy
    复制的意思,意思非常明确,但用起来是最要注意的。
    这个关键字类似 strong ,只能修饰 NSObject 对象,不能修饰基本数据类型。和 strong 不一样的地方是, copy 后的对象 ,指针地址是和之前不一样的,也就是说重新分配了一块内存,也就是所谓的深拷贝。这个关键字在用的时候,因为涉及到申请新的内存空间,所以要少用,能用 strong 的地方都用 strong ,只有必须用 copy 的地方才用 copy 。
    一般来说,使用 copy 修饰拥有可变类型的属性,如NSMutableArray、NSMutableDictionary、NSMutableString 。
    那么再引申去问,使用 copy 修饰的对象都是深拷贝么?其实不是。
    总结:不可变对象的copy操作是浅拷贝,其他操作都是深拷贝。

weak的原理

1、weak的原理在于底层维护了一张weak_table_t结构的hash表,key是所指对象的地址,value是weak指针的地址数组。
2、weak 关键字的作用是弱引用,所引用对象的计数器不会加1,并在引用对象被释放的时候自动被设置为 nil。
3、对象释放时,调用clearDeallocating函数根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容