关于copy属性的正确用法,copy和strong的区别

做过iOS开发的同学肯定都用过copy属性,但是copy属性和strong的区别可能还有很多人并不是很清楚,这一篇文章就专门讲一讲copy这个属性。

首先抛出本篇文章的结论:
可以简单的把copy属性理解为把目标参数copy,也就是拷贝之后再赋值给成员变量。

以下是生成set方法的源码,可以参考。

static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)
{
if (offset == 0) {
object_setClass(self, newValue);
return;
}

id oldValue;
id *slot = (id*) ((char*)self + offset);

if (copy) {
    newValue = [newValue copyWithZone:nil];
} else if (mutableCopy) {
    newValue = [newValue mutableCopyWithZone:nil];
} else {
    if (*slot == newValue) return;
    newValue = objc_retain(newValue);
}

if (!atomic) {
    oldValue = *slot;
    *slot = newValue;
} else {
    spinlock_t& slotlock = PropertyLocks[slot];
    slotlock.lock();
    oldValue = *slot;
    *slot = newValue;        
    slotlock.unlock();
}

objc_release(oldValue);

}

从这里可以看出来copy和strong的区别主要在于copy这个动作。
那么copy的作用到底是什么?这个动作对于不同Object又有什么不同作用呢?copy和mutableCopy又有什么区别呢?
这里再一次抛出结论:
对不可变变量(例如NSString)进行不可变拷贝(copy),是浅拷贝(引用计数+1),其他情况都是深拷贝。
对不可变变量(例如NSString)来说定义成copy,更加安全,但是效率也更低

为什么更加安全?
我们把一个变量定义成NSString,那一定是我们不希望它的值被任意改变。如果定义属性的时候使用strong,那就有可能存在被任意,或者意料之外改动的情况。
我们来看一个例子:

@interface ViewController ()
@property (nonatomic, strong) NSString* strongString;
@property (nonatomic, copy) NSString* copyedString;
@end

- (void)copyTest
{
    NSMutableString* mstr = [NSMutableString stringWithFormat:@"I'am mutableString"];
    self.strongString = mstr;
    self.copyedString = mstr;
    [self printAdress:mstr];
    
    [mstr insertString:@"and I'am copyed" atIndex:mstr.length];
    
    [self printString:mstr];
}

- (void)printAdress:(NSString*)str
{
    NSLog(@"*****************");
    NSLog(@"str:%p",str);
    NSLog(@"storng:%p",(_strongString));
    NSLog(@"copy:%p",(_copyedString));
}

- (void)printString:(NSString*)str
{
    NSLog(@"+++++++++++++");
    NSLog(@"str:%@",str);
    NSLog(@"storng:%@",(_strongString));
    NSLog(@"copy:%@",(_copyedString));
}

输出结果:

*****************
str:0x60000058fe10
storng:0x60000058fe10
copy:0x60000058fae0
+++++++++++++
str:I'am mutableStringand I'am copyed
storng:I'am mutableStringand I'am copyed
copy:I'am mutableString

由于strongString是定义成了strong,在被赋予一个NSMutableString的变量mstr之后,对mstr进行修改,strongString也被修改了。这相当于对一个不可变变量间接进行了修改。
为什么更低效?
原因很简单,因为需要深拷贝,需要重新开辟空间并且赋值。
但是,不是把属性定义成copy就万事大吉了,需要注意的是在类内部还是需要使用self.copyedString的方式或者[self setCopyedString]调用,如果直接_copyedString=mstring的方式还是不会起到效果,因为没有调用setter方法

Block属性最好使用copy

虽然对于Block来说,ARC环境下使用copy和strong的效果一样(因为即使是定义成strong,赋值的时候依然会为我们拷贝),但是我们最好使用copy修饰。
原因跟Block的内存分布有关系。
Block根据他们在内存的位置分为三种:
1.NSStackBlock(在栈区,超出作用域就会自动释放)。
2.NSMallocBlock(在堆区,生命周期由程序员手动管理)。
3.NSGlobalBlock(全局区)。
对于栈区的Block可以进行一次拷贝,把栈区的Block拷贝到堆区。
在MRC下必须使用copy,以完成拷贝。沿用到ARC下最好也用copy,以表明其工作原理。
关于Block的内存分布是一个非常复杂的话题,这里就不展开了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容