oc中copy的簡(jiǎn)單使用以及注意事項(xiàng)

OC中copy修飾@property

1.copy修飾字符串,可以防止外界修改內(nèi)部的數(shù)據(jù)

@interfaceStudent:NSObject@property(nonatomic,strong)NSString*name;@end

NSMutableString*temp=[[NSMutableString alloc]initWithFormat:@"lwl"];Student*stu=[[Student alloc]init];stu.name=temp;[temp appendString:@" test"];NSLog(@"name = %@",stu.name);

首先我們創(chuàng)建了一個(gè)Student類(lèi),并聲明了一個(gè)name屬性,修飾符為strong。在代碼二中,定義了一個(gè)變量temp可變字符串,并創(chuàng)建了stu實(shí)例。把temp字符串賦值給stu中的name屬性。最后temp字符串追加@“test”,最后打印出來(lái)的stu的name也會(huì)追加test;

2019-01-2714:50:25.484899+0800CopyUserProperty[8486:938202]Hello,World!2019-01-2714:50:25.485079+0800CopyUserProperty[8486:938202]name=lwl testProgram endedwithexit code:0

**解決辦法**

只需要將Student中的name屬性修飾的strong變成copy即可

@interfaceStudent:NSObject@property(nonatomic,copy)NSString*name;@end

2019-01-2715:12:39.131612+0800CopyUserProperty[9016:1066999]Hello,World!2019-01-2715:12:39.131878+0800CopyUserProperty[9016:1066999]name=lwlProgram endedwithexit code:0

**分析原因**

如果修飾符為strong,在將temp賦值給stu的name的時(shí)候,temp指向的對(duì)象會(huì)在引用計(jì)數(shù)(retaincount)會(huì)加1,相單于兩個(gè)變量同時(shí)指向了同一個(gè)對(duì)象,修改其中一個(gè)另外一個(gè)肯定會(huì)變換。如果修飾符為copy,在將temp賦值給stu的name的時(shí)候,會(huì)重新拷貝一個(gè)對(duì)象放在堆中,temp指向的對(duì)象的引用計(jì)數(shù)(retaincount)不會(huì)加1,temp和stu的name指向不同的對(duì)象。是深拷貝。

2.copy修飾block

block默認(rèn)存儲(chǔ)在棧中,棧中的block訪問(wèn)到外界的對(duì)象時(shí),不會(huì)進(jìn)行相應(yīng)的retain操作;如果block在堆中(Block_copy宏可以將block轉(zhuǎn)移到堆中),在訪問(wèn)外界的對(duì)象時(shí),會(huì)進(jìn)行相應(yīng)的retain操作。

Student*stu=[[Student alloc]init];NSLog(@"retainCount = %lu",[stu retainCount]);void(^myBlock)(int)=^(int age){NSLog(@"num = %@",stu);};myBlock(3);Block_copy(myBlock);NSLog(@"retainCount = %lu",[stu retainCount]);

Student類(lèi)新增block屬性

typedefvoid(^myBlock)(void);@interfaceStudent:NSObject@property(nonatomic,assign)myBlock pBlock;@property(nonatomic,copy)NSString*name;@end

Dog*d=[[Dog alloc]init];Student*stu=[[Student alloc]init];stu.pBlock=^{NSLog(@"d = %@",d);};[d release];stu.pBlock();[stu release];

在stu對(duì)象中的block中訪問(wèn)到d對(duì)象,因?yàn)閎lock修飾的屬性是assgin,block保存在棧中,所以對(duì)d對(duì)象的引用計(jì)數(shù)(retaincount)不會(huì)加1,d對(duì)象釋放之后,stu對(duì)用了block就會(huì)訪問(wèn)到僵尸對(duì)象,導(dǎo)致程序崩潰。

**解決方法**

typedefvoid(^myBlock)(void);@interfaceStudent:NSObject*注意:如果是block使用copy并不是拷貝,而是轉(zhuǎn)移*@property(nonatomic,copy)myBlock pBlock;@property(nonatomic,copy)NSString*name;@end

將block修飾符變?yōu)閏opy的時(shí)候,block會(huì)被轉(zhuǎn)移到堆中,會(huì)對(duì)其引用的對(duì)象增加引用計(jì)數(shù)。

3.copy修飾block的循環(huán)引用問(wèn)題

2019-01-2715:51:57.716059+0800CopyUserProperty[10115:1259494]d=<Dog:0x1005168e0>2019-01-2715:51:57.716220+0800CopyUserProperty[10115:1259494]-[Student dealloc]Program endedwithexit code:0

上面的代碼中Student對(duì)象可以釋放,但dog對(duì)象沒(méi)有釋放。

**解除方法**

只需要在block使用的對(duì)象前面加上__block修飾

__block Dog*d=[[Dog alloc]init];Student*stu=[[Student alloc]init];stu.pBlock=^{NSLog(@"d = %@",d);};[d release];stu.pBlock();[stu release];

2019-01-2716:04:59.728277+0800CopyUserProperty[10441:1288724]-[Dog dealloc]2019-01-2716:04:59.728615+0800CopyUserProperty[10441:1288724]d=<Dog:0x100682b30>2019-01-2716:04:59.728632+0800CopyUserProperty[10441:1288724]-[Student dealloc]Program endedwithexit code:0

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 Blocks是C語(yǔ)言的擴(kuò)充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了這...
    小人不才閱讀 3,884評(píng)論 0 23
  • 1.設(shè)計(jì)模式是什么? 你知道哪些設(shè)計(jì)模式,并簡(jiǎn)要敘述?設(shè)計(jì)模式是一種編碼經(jīng)驗(yàn),就是用比較成熟的邏輯去處理某一種類(lèi)型...
    龍飝閱讀 2,305評(píng)論 0 12
  • block.png iOS代碼塊Block 概述 代碼塊Block是蘋(píng)果在iOS4開(kāi)始引入的對(duì)C語(yǔ)言的擴(kuò)展,用來(lái)實(shí)...
    全棧農(nóng)民工閱讀 644評(píng)論 0 1
  • Block使用場(chǎng)景,可以在兩個(gè)界面的傳值,也可以對(duì)代碼封裝作為參數(shù)的傳遞等。用過(guò)GCD就知道Block的精妙之處。...
    Coder_JMicheal閱讀 827評(píng)論 2 1
  • 端午節(jié),你一個(gè)人嗎?不怕,我陪你。如果沒(méi)法遇見(jiàn),那也沒(méi)關(guān)系,我的心,為你留在這里。 這是工作后在外過(guò)的第二個(gè)端午節(jié)...
    半夏聽(tīng)海閱讀 374評(píng)論 0 0

友情鏈接更多精彩內(nèi)容