OC 屬性修飾詞retain assign等

#修飾詞retain、assign

***retain侈询、assign妻献、copy在@property中的使用實際上是通過控制set方法進行內(nèi)存管理。下面詳細介紹:***

1. retain

例如:

```

@class Dog

@property (nonatomic,retain) Dog *dog;

```

**注:nonatomic與atomic相對應(yīng)蜘犁,涉及線程翰苫,nonatomic相對atomic來說性能高,而聲明屬性時一般認為atomic,故需在此申明nonatmic**

這里使用了retain奏窑,那么set方法中导披,究竟如何體現(xiàn)

```

- (void)setDog:(Dog *)dog

{

if (_dog != dog) { //判斷是否需要重新賦值

[_dog release]; //釋放舊引用,計數(shù)器-1

_dog = [dog retain]; //重新賦值埃唯,計數(shù)器+1

}

}

```

2. assign:

例如:

```

@property (nonatomic,assign) int count;

```

這里使用了assign撩匕,那么在set方法中,究竟如何體現(xiàn)

```

- (void)setCount:(int)count

{

_count = count;

}

```

3. copy:

例如:

```

@property(nonatomic,copy)NSString *str;

```

這里使用了copy墨叛,那么在set方法中

```

- (void)setStr:(NSString *)str

{

if(_str != str) { //判斷是否需要重新賦值

[_str release]; //釋放舊引用止毕,計數(shù)器-1

_str = [str copy]; //重新賦值,使用copy

}

}

```

##總結(jié):

1. retain:先release舊值漠趁,在retain新值扁凛,在上例中_dog與dog最終指向同一塊內(nèi)存區(qū)域。

2. assign:直接賦值闯传,不考慮內(nèi)存管理谨朝。

3. copy:先release舊值,再copy新值甥绿,copy的本質(zhì)為復(fù)制該內(nèi)所存儲的內(nèi)容字币,重新創(chuàng)建一個對象賦給其相同的內(nèi)容,很明顯妹窖,在copy這個過程中也發(fā)生了一次retain纬朝,不過這是個全新的對象。在上例中骄呼,_str與str最終指向了不同的區(qū)域共苛,但其內(nèi)容一樣。

4. 從retain蜓萄、assign隅茎、copy的特點中:

retain一般適用于OC中的對象

assign一般適用于非OC對象,如int等普通類型

copy一般適用于NSString等不可變的對象嫉沽,因為是重新創(chuàng)建了對象辟犀,并且內(nèi)容不變,因此不用擔心后面的操作會對該屬性的值產(chǎn)生影響绸硕。

##實例分析:

假設(shè)str為對象p的屬性

```

@property (nonatomic,copy)NSString *str;

NSMutableString *s = [[NSMutableString alloc] initWithString:@"hello"];

p.str = s; //此時堂竟,str的值為@”hello“

[s appendString:@"world"]; //此時,s的值是”hello world“玻佩,但是str的值依然為”hello“出嘹。

```

但是如果開始時str的申明為:

```

@property(nonatomic,retain)NSString *str;

```

那么,在進行完[s appendString:@"world"]之后咬崔,str的值將變?yōu)椤県ello world“税稼。因為str與s共用一塊內(nèi)存烦秩,內(nèi)容完全相同,而s是可以改變的郎仆,所以s改變后只祠,str也將改變。

copy:建立一個索引計數(shù)為1的對象扰肌,然后釋放就對象 對NSString

對NSString它指出抛寝,在賦值時使用傳入值的一份拷貝∈镄瘢拷貝工作由copy方法執(zhí)行墩剖,此屬性只對那些實行了NSCopying協(xié)議的對象類型有效。

retain:釋放舊的對象夷狰,將舊對象的值賦予輸入對象,再提高輸入對象的索引計數(shù)為1

對其他NSObject和其子類

對參數(shù)進行release舊值郊霎,再retain新值

指定retain會在賦值時喚醒傳入值的retain消息沼头。此屬性只能用于Objective-C對象類型,而不能用于Core Foundation對象书劝。(原因很明顯进倍,retain會增加對象的引用計數(shù),而基本數(shù)據(jù)類型或者Core Foundation對象都沒有引用計數(shù))购对。

***注意:把對象添加到數(shù)組中時猾昆,引用計數(shù)將增加對象的引用計數(shù)次數(shù)+1***

retain的實際語法為:

- (void)setName:(NSString *)newName {

if (name != newName) {

[name release];

name = [newName retain];

}

}

copy與retain:

Copy其實是建立了一個相同的對象,而retain不是:

比如一個NSString對象骡苞,地址為0X1111,內(nèi)容為@”STR“

Copy到另一個NSString之后解幽,地址為0X2222贴见,內(nèi)容相同新的對象retain為1,舊有對象沒有變化

retain到另外一個NSString之后躲株,地址相同(建立一個指針片部,指針拷貝),內(nèi)容當然相同霜定,這個對象的retain值+1

也就是說retain是指針拷貝档悠,copy是內(nèi)容拷貝。

retain的set方法應(yīng)該是淺復(fù)制望浩,copy的set方法應(yīng)該是深復(fù)制了

copy另一個用法:

copy是內(nèi)容的拷貝辖所,對于像NSString的確實這樣

但是,如果是copy的是一個NSArray呢曾雕?

NSArray *array = [NSArray arrayWithObjects:@"hello",@"world",@"baby"];

NSArray *array2 = [array copy];

這個時候奴烙,系統(tǒng)的確是為array2開辟了一塊內(nèi)存空間,但是我們要認識到的是,array2中的每個元素切诀,只是copy了指向array中相對應(yīng)元素的指針揩环。這便是所謂的”淺復(fù)制“。

assign:簡單輔值幅虑,不更改索引計數(shù)

對基礎(chǔ)數(shù)據(jù)類型(例如NSInteger丰滑,CGFloat)和C數(shù)據(jù)類型(int,float倒庵,double褒墨,char等)適用簡單數(shù)據(jù)類型

此標記說明設(shè)置器直接進行賦值,這也是默認值擎宝。在使用垃圾收集的應(yīng)用程序中郁妈,如果你要一個屬性使用assign,且這個類符合NSCopying協(xié)議绍申,你就要明白指出這個標記噩咪,而不是簡單地使用默認值,否則的話极阅,你將得到一個編譯警告胃碾。這再次向編譯器說明你確實需要賦值,即使它是可拷貝的筋搏。

weak和strong屬性只有在你打開ARC時才會被要求使用仆百,這時你是不能使用retain release autorelease操作,ARC會自動為你做好這些操作奔脐,但是你需要在對象屬性上使用weak和strong俄周,其中strong就相當于retain屬性,而weak相當于assign髓迎。

strong關(guān)鍵字與retain相似栈源,引用計數(shù)自動+1,用實例更能說明一切

@property(nonatomic,strong)NSString *string1;

@property(nonatomic,string)NSString *string2;

self.string1 = @"String1";

self.string2 = self.string1;

self.string1 = nil;

NSLog(@"String2 = %@",self.string2);

結(jié)果是:String2 = String1

***由于string2是strong定義的屬性竖般,所以引用計數(shù)+1甚垦,使得它們指向同一地址內(nèi)容為:@”String1“,不可變字符串每次賦值都會重新開辟新地址涣雕。***

接著我們來看weak關(guān)鍵字:

如果這樣聲明兩個屬性:

@property(nonatomic,strong)NSString *string1;

@property(nonatomic,weak)NSString *string2;

self.string1 = @"String1";

self.string2 = self.string1;

self.string1 = nil;

NSLog(@"String2 = %@",self.string2);

結(jié)果是:String2 = null

***分析下艰亮,由于self.string1與self.string2指向同一地址,且string2沒有retain內(nèi)存地址挣郭,而self.string1 = nil釋放了內(nèi)存迄埃,所以string1為nil。聲明為weak的指針兑障,指針指向的地址一旦被釋放侄非,這些指針都將被賦值為nil蕉汪。這樣的好處能有效的防止野指針。在c/c++開發(fā)過程中逞怨,為何大牛都說指針的控件釋放后者疤,都要講指針賦為NULL。在這兒用weak關(guān)鍵字幫我們做了這一步叠赦。***

##copy

特點:

1. 修改源文件的內(nèi)容驹马,不會影響副文本;

2. 修改副文本的內(nèi)容除秀,不會影響源文件糯累;

OC中copy的作用是:利用一個源對象產(chǎn)生一個副本對象

特點:

1. 修改源對象的屬性和行為,不會影響副本對象册踩;

2. 修改副本對象的屬性和行為泳姐,不會影響源對象。

如何使用copy功能

一個對象可以調(diào)用copy或mutableCopy方法來創(chuàng)建一個副本對象暂吉。

1. copy:創(chuàng)建的時不可變副本(NSString仗岸、NSArray、NSDictionary)借笙。

2. mutableCopy:創(chuàng)建的可變副本(NSMutableString、NSMutableArray较锡、NSMutableDictionary)业稼。

使用copy功能的前提:

1. copy:需要遵守NSCopying協(xié)議,實現(xiàn)copyWithZone:方法蚂蕴。

```

@protocol NSCopying

- (id)copyWithZone:(NSZone *)zone;

@end

```

2. mutableCopy:需要遵守NSMutableCopy協(xié)議低散,實現(xiàn)mutableCopyWithZone:方法

```

@protocol NSMutableCopying

- (id)mutableCopyWithZone:(NSZone *)zone;

@end

```

###深復(fù)制和淺復(fù)制的區(qū)別:

**深拷貝**

特點:

1. 源對象和副本對象是不同的兩個對象;

2. 源對象引用計數(shù)器不變骡楼,副本對象計數(shù)器為1(因為是新產(chǎn)生的)熔号。

本質(zhì):產(chǎn)生了新對象

**淺拷貝**

特點:

1. 源對象和副本對象是同一對象;

2. 源對象(副本對象)引用計數(shù)+1鸟整,相當于做一次retain操作引镊。

本質(zhì):沒有產(chǎn)生新的對象。

常見賦值如下:![](http://oh6yavwvf.bkt.clouddn.com/00027.png)

***只有源對象和副本對象都不可變時篮条,才是淺復(fù)制弟头,其他都是深復(fù)制。***

```

/**

NSMutableString調(diào)用mutablecopy:深復(fù)制

*/

void mutableStringMutableCopy()

{

NSMutableString *srcStr = [NSMutableString stringWithFormat:@"age is %d",10];

NSMutableString *copyStr = [srcStr mutableCopy];

[copyStr appendString:@"abc"];

NSLog(@"srcStr=%@,copyStr=%@",srcStr,copyStr);

}

/**

NSMutableString調(diào)用copy:深復(fù)制

*/

void mutableStringCopy()

{

NSMutableString *srcStr = [NSMutableString stringWithFormat@"age is %d",10];

NSString *copyStr = [srcStr copy];

[srcStr appendString:@"abc"];

NSLog(@"srcStr=%p, copyStr=%p", srcStr, copySt);

}

/**

NSString調(diào)用mutablecopy:深復(fù)制

*/

void stringMutableCopy()

{

NSString *srcStr = [NSString stringWithFormat:@"age is %d",10];

NSMutableString *copyStr = [srcStr mutableCopy];

[copyStr appendString:@"abc"];

NSLog(@"srcStr=%@, copyStr=%@", srcStr, copyStr);

}

/**

NSString調(diào)用copy:淺復(fù)制

*/

void stringCopy()

{

//copy:產(chǎn)生的肯定是不可變副本

//如果是不可變對象調(diào)用copy方法產(chǎn)出不可變副本涉茧,那么不會產(chǎn)生新的對象

NSString *srcStr = [NSString stringWithFormat:@"age is %d",10];

NSString *copyStr = [srcStr copy];

NSLog(@"%p %p",srcStr,copyStr);

}

```

文章屬于摘抄搬磚赴恨!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市伴栓,隨后出現(xiàn)的幾起案子伦连,更是在濱河造成了極大的恐慌雨饺,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惑淳,死亡現(xiàn)場離奇詭異额港,居然都是意外死亡,警方通過查閱死者的電腦和手機汛聚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門锹安,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人倚舀,你說我怎么就攤上這事叹哭。” “怎么了痕貌?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵风罩,是天一觀的道長钻心。 經(jīng)常有香客問我决侈,道長,這世上最難降的妖魔是什么九巡? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任哺徊,我火速辦了婚禮室琢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘落追。我一直安慰自己盈滴,他們只是感情好,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布轿钠。 她就那樣靜靜地躺著巢钓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疗垛。 梳的紋絲不亂的頭發(fā)上症汹,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機與錄音贷腕,去河邊找鬼背镇。 笑死,一個胖子當著我的面吹牛泽裳,可吹牛的內(nèi)容都是我干的芽世。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼诡壁,長吁一口氣:“原來是場噩夢啊……” “哼济瓢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起妹卿,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤旺矾,失蹤者是張志新(化名)和其女友劉穎蔑鹦,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箕宙,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡嚎朽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了柬帕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哟忍。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖陷寝,靈堂內(nèi)的尸體忽然破棺而出锅很,到底是詐尸還是另有隱情,我是刑警寧澤凤跑,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布爆安,位于F島的核電站,受9級特大地震影響仔引,放射性物質(zhì)發(fā)生泄漏扔仓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一咖耘、第九天 我趴在偏房一處隱蔽的房頂上張望翘簇。 院中可真熱鬧,春花似錦儿倒、人聲如沸版保。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蹈垢,卻和暖如春慷吊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背曹抬。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工溉瓶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人谤民。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓堰酿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親张足。 傳聞我的和親對象是個殘疾皇子触创,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容