貓貓整理問題之:copy,對象自訂copy,自訂copy

來源:互聯網
上載者:User

貓貓整理問題之:copy,對象自訂copy,自訂copy

貓貓分享,必須精品
原文地址:http://blog.csdn.net/u013357243?viewmode=contents

copycopy的正目的

copy 目的:建立一個副本,彼此修改,各不干擾
Copy(不可變)和MutableCopy(可變)針對Foundation架構的資料類型。
對於自訂類,copy就是可變的。

可變數組的copy

這裡用NSMutableArray為例子。

// 可變=》可變&不可變,記憶體位址都會變化void copyDemo1(){    NSMutableArray *arrayM = [NSMutableArray arrayWithObjects:@(1), @(2), nil];    NSLog(@"%@ %p %@", arrayM, arrayM, arrayM.class);    // 1. 可變 => 可變    NSMutableArray *aM = [arrayM mutableCopy];    NSLog(@"%@ %p %@", aM, aM, aM.class);    // 2. 可變 => 不可變    NSArray *a = [arrayM copy];    NSLog(@"%@ %p %@", a, a, a.class);}

由結果我們得到一下結論
1:arrayM,aM,a是三個不同的對象
2:可變 => 可變 (arrayM是可變的,用mutableCopy給aM 得出aM.class是NSArrayM )
3:可變 => 不可變(aM是可變的,用copy給a 得出a.class是NSArrayI)

不可變數組的copy
void copyDemo2(){    NSArray *array = @[@(1), @(2)];    NSLog(@"%@ %p %@", array, array, array.class);    // 1. 不可變 => 可變    NSMutableArray *aM = [array mutableCopy];    NSLog(@"%@ %p %@", aM, aM, aM.class);    // 2. 不可變 => 不可變(淺複製)    // 指標的複製,引用計數+1    NSArray *a = [array copy];    NSLog(@"%@ %p %@", a, a, a.class);}

由上結果我們得到結論
1:不可變 => 可變 記憶體位址變了,class由NSArrayI=>NSArrayM
2:不可變 => 不可變 記憶體位址一致,class由NSArrayI=>NSArrayI
作用是指標的複製,引用計數+1。術語(淺複製)

3:淺複製:不可變=>不可變   深複製:其他三種情況!   (在這裡記憶時候記住都不能改就是淺複製,能改就是深複製,相對於記憶四中情況更容易記憶。)
哪裡用的最多呢?

這裡用的最多

@property (nonatomic, copy) NSString *name;

NSString
Block

都使用copy屬性,copy屬性,在賦值時,會預設做一次copy操作,讓他變成“不可變的類型”strong相當於MRC中的retain,在賦值時,只是引用計數+1

在@property中使用什麼楊的類型說明他,他就有什麼樣的方法。
例如這段代碼:

 NSMutableString *strM = [NSMutableString stringWithString:@"zhangsan"];    NSLog(@"%@ %p %@", strM, strM, strM.class);    Person *p = [[Person alloc] init];    p.name = strM;    NSLog(@"%@ %p %@", p.name, p.name, p.name.class);    // 修改"源",p.name會跟著修改    [strM setString:@"lisi"];    NSLog(@"==== %@ %p", strM, strM);    NSLog(@"%@ %p", p.name, p.name);

如果用strong來說明person的name,當我們修改strM的時候,p.name也會跟著改,如果用的時copy的話,那麼他就不會被修改。這裡取決於Person類中的@property
簡單理解,如果用了copy就是複製一個String給name
而如果用了strong,就僅僅是引用計數+1。
p.name能不能修改呢?這裡我們不能直接修改,我們需要用一個萬能指標。

// 修改p.name    id obj = p.name;    [obj setString:@"wangwu"];    NSLog(@"==== %@ %p", strM, strM);    NSLog(@"%@ %p", p.name, p.name);

這要用strong能改,這樣類會變得不安全。我們把strong改成copy
當我們修改“源”的時候

[strM setString:@"lisi"];

p.name還是原樣的。
而這時候修改屬性的方法編譯沒有問題,但是運行時候會報錯

Attempt to mutate immutable object with xxx
視圖修改一個不可變的類型,使用方法xxx

對於”可變類型”的屬性,不要使用copy描述符定義,否則賦值後,就是不可變了!

copy自訂對象[object copy]

想要讓對象能用copy方法 [p copy]
(自訂對象要實現copy功能)
1> 遵守NSCopying協議(本質上就是方便程式員編寫代碼時候,有快捷提示)
2> 實現- (id)copyWithZone:(NSZone *)zone
(zone,地區,很少用)
所有的copy方法,最終都會調用copyWithZone方法
copy操作一個對象,複製給一個新的對象。

- (id)copyWithZone:(NSZone *)zone{    // 1> 執行個體化對象,self 是對象    // self.class能夠保證繼承的子類同樣使用copy方法    Person *p = [[self.class alloc] init];    // 2> 給屬性賦值    p.name = self.name;    p.age = self.age;    // 3> 返回新對象    return p;}

這時候我們這樣調用

void copyDemo5(){    Person *p = [[Person alloc] init];    p.name = @"zhangsan";    p.age = 18;    NSLog(@"%@", p);    Person *p1 = [p copy];    p1.name = @"lisi";    NSLog(@"%@", p1);}


這時候我們就能調用自己定義的類對象的copy方法了,並且可以產生一個對象。
注意:這裡的p1.name = @”lisi”並不是修改,而是重新賦值。不要讓copy給弄迷糊了。

ps:建立iOS交流學習群:304570962
可以加貓貓QQ:1764541256 或則znycat
讓我們一起努力學習吧。
原文:http://blog.csdn.net/u013357243?viewmode=contents

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.