属性修饰符分析

基础概念


atomic & nonatomic

决定编译器生成的setter/getter是否为原子操作 。
atomic是Objc使用的一种线程保护技术,防止在某个操作未完成时被另外一个线程操作,造成数据错误。然而这种多线程安全机制对资源的占用很大,在iPhone等小型设备中,除非需要使用多线程之间通讯编程,采用这种技术需要慎重考量。
一般情况下,使用nonatomic来修饰成员变量,存取器直接返回一个值,而不需要管当不同的线程同时访问时会发生什么。

readwrite & readonly

任何属性都可以声明为readwrite或readonly,且默认设置为readwrite 。
将一个属性声明为readwrite时,编译器将会为这个属性生成setter和getter。
将一个属性生命为readonly时,编译器将只会生成getter。

assign

直接赋值,不更改引用计数,一般用于基础数据类型和C语言类型数据。

retain

释放旧对象,并使传入的新对象引用计数+1。
此属性只能用于NSObject及其子类,而不能用于Core Foundation(因为其没有使用引用计数,需要另外使用CFRetain和CFRelease来进行CF的内存管理)。

strong

释放旧对象,并使传入的新对象引用计数+1。
在ARC下,strong为对象类型属性声明时的默认值。

copy

创建一个引用计数为1的新对象,这个新对象是传入对象的拷贝。
会拷贝传入的对象(即创建一个引用计数为1的新对象,但是内容与传入对象相同),并把新对象赋值给实例变量。

weak

弱引用,要求不保留传入的属性(既不会使传入的对象引用计数+1)。
类似于assign,但与assign不同的是,当它们指向的对象被释放后,weak会被自动置为nil,而assign则不会。


进阶问题


strong & weak

这里采用 stack overflow 上的一个对强/弱引用的解释

如果将对象想象成一只想要逃跑(be deallocated)的狗的话。

强引用就像是拴住狗的绳子。只要你还还牵着拴住狗的绳子,狗就逃跑不了。如果有五个人都将绳子拴住了狗,那么除非五个人都解开了绳子,否则狗就不可能逃跑。

而弱引用,就像一个小孩子指着狗说:看,那里有一直狗。只要狗仍被狗绳拴着,小孩就还能看见狗,他们仍会指着它。然而一但狗绳被解开,狗就会逃跑而不管多少小孩子指着它。

copy & retain

copy实际上是建立了一个新的相同的对象,而retain是将传入对象的引用计数+1 。

深拷贝 & 浅拷贝

浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间 。浅拷贝只是对对象的简单拷贝,让几个对象共用一片内存,当内存销毁的时候,指向这片内存的几个指针需要重新定义才可以使用,要不然会成为野指针。
在iOS中,使用retain修饰的属性变量,就是一种浅拷贝。它既让几个指针共用同一片内存空间,又可以在release时由于计数的存在,不会轻易的销毁内存,达到更加简单使用的目的。
深拷贝是指拷贝对象的具体内容,而内存地址是自主分配的,拷贝结束之后,两个对象虽然存的值是相同的,但是内存地址不一样,两个对象也互不影响,互不干涉。
值得注意的是,对可变对象如NSMutableArray等无论是copy还是mutableCopy都是进行了深拷贝。

@property & @synthesize

如果我们希望使用默认的实例变量命名方式,那么我们在.m文件中就不需要使用@synthesize声明,系统会帮我们自动完成。如果我们希望自己命名实例变量命,那么我们就使用@synthesize显式声明我们希望的实例变量名 。

block作为实例变量为何要用copy修饰?

因为block如果在栈上的话,其所属的变量作用域结束,该block就被释放掉,block中的__block变量也同时被释放掉。为了解决栈块在其变量作用域结束之后被释放掉的问题,我们就需要把block复制到堆中。

为什么NSString、NSDictionary、NSArray要使用copy修饰?

对于NSString、NSDictionary、NSArray等经常使用copy关键字,是因为它们有对应的可变类型:NSMutableString、NSMutableDictionary、NSMutableArray,它们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性时拷贝一份。

weak、copy、strong、assgin分别用在什么地方?

什么情况下会使用weak关键字?

  • 在ARC中,出现循环引用的时候,会使用weak关键字。
  • 自身已经对它进行了一次强引用,没有必要再强调引用一次。

assgin适用于基本的数据类型,比如NSInteger、BOOL等。

NSString、NSArray、NSDictionary等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary;

除了上面的三种情况,剩下的就使用strong来进行修饰。


作者

Y2hlbmdsZWk=

发布于

2015-09-02

更新于

2021-09-01

许可协议