iOS開發 — 屬性用copy、strong修飾的區別 – iPhone手機開發 iPhone軟體開發教學課程

Copy,Strong的區別需要瞭解點內存管理的知識,Strong是ARC下引入的修飾,相當於手動管理內存(MRC)下的retain,在相關代碼下,常常看到有的人用copy修飾NSString,NSArray,NSDictionary..等存在可變與不可變之分的對象,常常會用copy,而不是strong,下面代碼來解釋一下strong與copy的區別:

先說明一下什麼叫做淺拷貝,什麼叫做深拷貝;

淺Copy:可以理解為指針的復制,隻是多瞭一個指向這塊內存的指針,共用一塊內存。

深Copy:理解為內存的復制,兩塊內存是完全不同的,也就是兩個對象指針分別指向不同的內存,互不幹涉。

首先在類延展中聲明兩個屬性變量

@property(nonatomic,strong)NSString*stringStrong;//strong修飾的字符串對象

@property(nonatomic,copy)NSString*stringCopy;//copy修飾的字符串對象

接著創建兩個不可變字符串(NSString)

//新創建兩個NSString對象

NSString*strong1=@"IamStrong!";

NSString*copy1=@"IamCopy!";

將兩個屬性分別進行賦值

//初始化兩個字符串

self.stringStrong=strong1;

self.stringCopy=copy1;

分別打印一下四個變量的內存地址:

NSLog(@"strong1=%p",strong1);

NSLog(@"stringStrong=%p",self.stringStrong);

NSLog(@"copy1=%p",copy1);

NSLog(@"stringCopy=%p",self.stringCopy);

結果如下:可以看出,此時無論是strong修飾的字符串還是copy修飾的字符串,都進行瞭淺Copy.

2016-02-2918:59:06.332StrongOrCopy[5046:421886]strong1=0x10a0b3078

2016-02-2918:59:06.332StrongOrCopy[5046:421886]stringStrong=0x10a0b3078

2016-02-2918:59:06.332StrongOrCopy[5046:421886]copy1=0x10a0b3098

2016-02-2918:59:06.332StrongOrCopy[5046:421886]stringCopy=0x10a0b3098

如果創建兩個不可變字符串對象(NSMutableString)呢

//新創建兩個NSMutableString對象

NSMutableString*mutableStrong=[NSMutableStringstringWithString:@"StrongMutable"];

NSMutableString*mutableCopy=[NSMutableStringstringWithString:@"CopyMutable"]; 分別對屬性再次進行賦

self.stringStrong=mutableStrong;

self.stringCopy=mutableCopy;

分別打印一下四個變量的地址:結果如下:這時就發現瞭,用strong修飾的字符串依舊進行瞭淺Copy,而由copy修飾的字符串進行瞭深Copy,所以mutableStrong與stringStrong指向瞭同一塊內存,而mutableCopy和stringCopy指向的是完全兩塊不同的內存。

2016-02-2918:59:06.332StrongOrCopy[5046:421886]mutableStrong=0x7fccba425d60

2016-02-2918:59:06.332StrongOrCopy[5046:421886]stringStrong=0x7fccba425d60

2016-02-2918:59:06.332StrongOrCopy[5046:421886]mutableCopy=0x7fccba40d7c0

2016-02-2918:59:06.333StrongOrCopy[5046:421886]stringCopy=0x7fccba4149e0

那麼有什麼用呢,實例來看一下有什麼區別:

首先是對不可變字符串進行操作:

[objc]view plaincopy

 

在CODE上查看代碼片

派生到我的代碼片

 

//新創建兩個NSString對象

NSString*strong1=@"IamStrong!";

NSString*copy1=@"IamCopy!";

//初始化兩個字符串

self.stringStrong=strong1;

self.stringCopy=copy1;

//兩個NSString進行操作

[strong1stringByAppendingString:@"11111"];

[copy1stringByAppendingString:@"22222"]; 分別對在字符串後面進行拼接,當然這個拼接對原字符串沒有任何的影響,因為不可變自字符串調用的方法都是有返回值的,原來的值是不會發生變化的.打印如下,對結果沒有任何的影響:

2016-02-2919:15:26.729StrongOrCopy[5146:439360]strong1=IamStrong!

2016-02-2919:15:26.729StrongOrCopy[5146:439360]stringStrong=IamStrong!

2016-02-2919:15:26.729StrongOrCopy[5146:439360]copy1=IamCopy!

2016-02-2919:15:26.729StrongOrCopy[5146:439360]stringCopy=IamCopy!

然後是對可變字符串進行操作:

//新創建兩個NSMutableString對象

NSMutableString*mutableStrong=[NSMutableStringstringWithString:@"StrongMutable"];

NSMutableString*mutableCopy=[NSMutableStringstringWithString:@"CopyMutable"];

//初始化兩個字符串

self.stringStrong=mutableStrong;

self.stringCopy=mutableCopy;

//兩個MutableString進行操作

[mutableStrongappendString:@"Strong!"];

[mutableCopyappendString:@"Copy!"];

再來看一下結果:對mutableStrong進行的操作,由於用strong修飾的stringStrong沒有進行深Copy,導致共用瞭一塊內存,當mutableStrong對內存進行瞭操作的時候,實際上對stringStrong也進行瞭操作; 相反,用copy修飾的stringCopy進行瞭深Copy,也就是說stringCopy與mutableCopy用瞭兩塊完全不同的內存,所以不管mutableCopy進行瞭怎麼樣的變化,原來的stringCopy都不會發生變化.這就在日常中避免瞭出現一些不可預計的錯誤。

2016-02-2919:20:27.652StrongOrCopy[5245:446189]stringStrong=StrongMutableStrong!

2016-02-2919:20:27.652StrongOrCopy[5245:446189]mutableStrong=StrongMutableStrong!

2016-02-2919:20:27.652StrongOrCopy[5245:446189]stringCopy=CopyMutable

2016-02-2919:20:27.652StrongOrCopy[5245:446189]mutableCopy=CopyMutableCopy!

這樣看來,在不可變對象之間進行轉換,strong與copy作用是一樣的,但是如果在不可變與可變之間進行操作,那麼樓主比較推薦copy,這也就是為什麼很多地方用copy,而不是strong修飾NSString,NSArray等存在可變不可變之分的類對象瞭,避免出現意外的數據操作.

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *