我做iOS开发已经一年半了,但是对于Objective-C的基础知识总是没有搞得特别清楚,一直处于大概知道,虽说对于一般需求而言,不知道也没关系,但是不搞清楚的话早晚要栽跟头。
以下讨论都是假定内存管理机制为ARC,Objective-C property 翻译为属性,attributes 翻译为属性修饰符。
原子性修饰符
atomic保证对一个成员变量的访问是原子的。所谓原子的,是指当对象的成员变量同时被多个线程并发访问时,独占该变量的访问权,可以理解为setter和getter操作都被加了锁。
但是atomic并不意味着线程安全,该机制只保证多个线程访问共享变量时彼此互斥,而对线程的访问顺序并无限定。比方说一个共享变量,在同一时间,有一个线程读取该变量的值,另一个线程写该变量的值,那么读线程读到的值有可能是写操作之前的值,也有可能是写操作执行以后的值。
the synthesized accessors ensure that a value is always fully retrieved by the getter method or fully set via the setter method, even if the accessors are called simultaneously from different threads.
访问控制修饰符
readonly表示该属性为只读的,而readwrite则是允许读写。如果不希望外部修改一个属性,那么请在头文件里面将起声明为readonly,如果在实现时又必须要修改该属性,那么在实现文件中将其声明为readwrite。
这里的原则是如果readonly能满足需求,就不要用readwrite,放大属性的写操作作用域简直就是灾难。
内存管理修饰符
谈论内存管理之前,需要先清楚一点,Objective-C中的属性主要有两种,一种是基本类型,也即值(value type),比如int float等。另外一种是对象类型(object type),或者说引用类型(reference type),其中对象类型的实例一定分配在堆(heap)上,并且通过指针指向该实例。
strong/retain,strong是在ARC引入以后新增的属性修饰符,并且只能修饰对象类型。当一个对象被strong属性指向时,其引用计数+1。retain是ARC之前的产物,意义和strong相同,不过在启用ARC的项目中,建议使用strong而非retain。至于为什么,没有为什么,有时候多问一下为什么是好事,而有时候不问为什么也是好事。
weak也只能修饰对象类型,weak属性指向对象以后,该对象引用计数不会发生变化,并且当对象被释放以后,属性会自动指向nil。weak主要用于解决循环引用问题,防止内存泄露,其次对象释放后,weak属性被自动置为nil的机制也能防止访问已释放对象导致的EXC_BAD_ACCESS崩溃。
copy是创建一个新对象,并将属性指向新建的对象,并对其强引用。当属性被赋值以后,如果不希望原对象的修改影响到该属性指向的对象,那么请将属性修饰符设为copy。
assign用于修饰值类型,比如int或float等这一类基本类型,直观理解就是赋值。
参考
https://academy.realm.io/posts/tmi-objective-c-property-attributes/
网友评论