property中的copy屬性

       在聲明property屬性時,如果是一個NSString的變量,那麼絕大多數情況下都要用到copy,這是爲什麼呢?這是因爲用了copy之後更加安全,減少了代碼之間的耦合度,屬性的值更不容易被改變。

 

首先要明白兩個概念,深複製與淺複製的區別:

深複製:複製對象的內存區域和指針,複製後的對象與原有對象相互獨立

淺複製:僅僅複製指針,複製後兩個指針指向同一塊內存區域,複製後的對象與原有對象相互影響

 

明白了這兩個概念就更容易理解了,先通過如下的例子直觀瞭解一下copy的好處:

首先定義了一個HITStudent類,裏面包含了一個用copy修飾的stuName屬性和一個被assign修飾的stuNumber屬性,此處nonatomic是線程安全的意思,如果不寫默認爲atomic。

#import <Foundation/Foundation.h>

@interface HITStudent : NSObject

@property (nonatomic,copy)NSString *stuName;

@property (nonatomic,assign)NSString *stuNumber;

@end


在主函數中先創建一個名爲stu1的HITStudent對象,並把該對象的stuName屬性和stuNunber屬性分別賦值爲xgc和123,之後我們對可變字符串name和number進行修改,再次打印stu1的兩個屬性我們發現用了copy修飾的stuName屬性沒有變化,但是用assign修飾的stuNumber屬性的值卻被改變了。

#import <Foundation/Foundation.h>

#import "HITStudent.h"

int main(int argc,constchar * argv[]) {

    @autoreleasepool {

        HITStudent *stu1 = [[HITStudentalloc]init];

        NSMutableString *name = [NSMutableStringstringWithFormat:@"xgc"];

        NSMutableString *number = [NSMutableStringstringWithFormat:@"123"];;

        stu1.stuName = name;

        stu1.stuNumber = number;

        NSLog(@"學生的姓名爲:%@",stu1.stuName);

        NSLog(@"學生的號碼爲:%@",stu1.stuNumber);

        

        [name appendString:@"HIT"];

        [number appendString:@"456"];

        NSLog(@"更改後學生的姓名爲:%@",stu1.stuName);

        NSLog(@"更改後學生的號碼爲:%@",stu1.stuNumber);

    

    }

    return0;

}


打印結果如下:

2016-04-18 10:44:06.025 copy[1230:46766]學生的姓名爲:xgc

2016-04-18 10:44:06.027 copy[1230:46766]學生的號碼爲:123

2016-04-18 10:44:06.027 copy[1230:46766]更改後學生的姓名爲:xgc

2016-04-18 10:44:06.027 copy[1230:46766]更改後學生的號碼爲:123456

Program ended with exit code: 0


由此我們可以得出結論:使用copy修飾NSString的時候,如果可變字符串改變了,被可變字符串的屬性不會改變


下面我們來分析一下原理:

assign和copy實際上是通過set方法來進行內存管理,當我們在ARC模式下使用assign時,系統會自動生成如下set方法:

-(void)setStuName:(NSString *)stuName

{

    _stuName = stuName;

}


而使用copy時會生成如下set方法:

-(void)setStuName:(NSString *)stuName

{

    if (_stuName != stuName) {

        [_stuName release];

        _stuName = [stuNamecopy];

    }



具體來說,assign是直接賦值,讓屬性與原來的可變字符串指向了同一塊內存區域,這樣的話當可變字符串指向的內存區域的值改變的時候,屬性的值自然也跟着改變,賦值相當於淺複製;

而copy的本質是先release原有的值,再複製該內存所儲存的內容,可以理解爲先做了一次release,又做了一次retain,但之後得到了一個全新的對象,擁有不同的內存區域,因此改變原有的字符串不會對屬性的值產生影響,copy賦值相當於深複製。

發佈了28 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章