轉(zhuǎn)載Qデ臁!渐裂!
轉(zhuǎn)自:http://www.lvtao.net/ios/504.html
@property與@synthesize是成對(duì)出現(xiàn)的阳液,可以自動(dòng)生成某個(gè)類成員變量的存取方法繁疤。在Xcode4.5以及以后的版本咖为,@synthesize可以省略。
1.atomic與nonatomic
atomic:默認(rèn)是有該屬性的稠腊,這個(gè)屬性是為了保證程序在多線程情況案疲,編譯器會(huì)自動(dòng)生成一些互斥加鎖代碼,避免該變量的讀寫不同步問(wèn)題麻养。
nonatomic:如果該對(duì)象無(wú)需考慮多線程的情況褐啡,請(qǐng)加入這個(gè)屬性,這樣會(huì)讓編譯器少生成一些互斥加鎖代碼鳖昌,可以提高效率备畦。
2.readwrite與readonly
readwrite:這個(gè)屬性是默認(rèn)的情況低飒,會(huì)自動(dòng)為你生成存取器。
readonly:只生成getter不會(huì)有setter方法懂盐。
readwrite褥赊、readonly這兩個(gè)屬性的真正價(jià)值,不是提供成員變量訪問(wèn)接口莉恼,而是控制成員變量的訪問(wèn)權(quán)限拌喉。
3.strong與weak
strong:強(qiáng)引用,也是我們通常說(shuō)的引用俐银,其存亡直接決定了所指向?qū)ο蟮拇嫱瞿虮场H绻淮嬖谥赶蛞粋€(gè)對(duì)象的引用,并且此對(duì)象不再顯示在列表中捶惜,則此對(duì)象會(huì)被從內(nèi)存中釋放田藐。
weak:弱引用,不決定對(duì)象的存亡吱七。即使一個(gè)對(duì)象被持有無(wú)數(shù)個(gè)弱引用汽久,只要沒(méi)有強(qiáng)引用指向它,那么還是會(huì)被清除踊餐。
strong與retain功能相似景醇;weak與assign相似,只是當(dāng)對(duì)象消失后weak會(huì)自動(dòng)把指針變?yōu)閚il;
4.assign吝岭、copy三痰、retain
assign:默認(rèn)類型,setter方法直接賦值苍碟,不進(jìn)行任何retain操作,不改變引用計(jì)數(shù)撮执。一般用來(lái)處理基本數(shù)據(jù)類型微峰。
retain:釋放舊的對(duì)象(release),將舊對(duì)象的值賦給新對(duì)象抒钱,再令新對(duì)象引用計(jì)數(shù)為1蜓肆。我理解為指針的拷貝,拷貝一份原來(lái)的指針谋币,釋放原來(lái)指針指向的對(duì)象的內(nèi)容仗扬,再令指針指向新的對(duì)象內(nèi)容。
copy:與retain處理流程一樣蕾额,先對(duì)舊值release早芭,再copy出新的對(duì)象,retainCount為1.為了減少對(duì)上下文的依賴而引入的機(jī) 制诅蝶。我理解為內(nèi)容的拷貝退个,向內(nèi)存申請(qǐng)一塊空間募壕,把原來(lái)的對(duì)象內(nèi)容賦給它,令其引用計(jì)數(shù)為1语盈。對(duì)copy屬性要特別注意:被定義有copy屬性的對(duì)象必須要 符合NSCopying協(xié)議舱馅,必須實(shí)現(xiàn)- (id)copyWithZone:(NSZone *)zone方法。
也可以直接使用:
使用assign: 對(duì)基礎(chǔ)數(shù)據(jù)類型 (NSInteger刀荒,CGFloat)和C數(shù)據(jù)類型(int, float, double, char, 等等)
使用copy: 對(duì)NSString
使用retain: 對(duì)其他NSObject和其子類
5.getter setter
getter:是用來(lái)指定get方法的方法名
setter:是用來(lái)指定set訪求的方法名
在@property的屬性中代嗤,如果這個(gè)屬性是一個(gè)BOOL值,通常我們可以用getter來(lái)定義一個(gè)自己喜歡的名字缠借,例如:
@property (nonatomic, assign,getter=isValue) boolean value;
@property (nonatomic, assign,setter=setIsValue) boolean value;
一,retain, copy, assign區(qū)別
1.
假設(shè)你用malloc分配了一塊內(nèi)存干毅,并且把它的地址賦值給了指針a,后來(lái)你希望指針b也共享這塊內(nèi)存烈炭,于是你又把a(bǔ)賦值給(assign)了b溶锭。此時(shí)a
和b指向同一塊內(nèi)存,請(qǐng)問(wèn)當(dāng)a不再需要這塊內(nèi)存符隙,能否直接釋放它趴捅?答案是否定的,因?yàn)閍并不知道b是否還在使用這塊內(nèi)存霹疫,如果a釋放了拱绑,那么b在使用這塊
內(nèi)存的時(shí)候會(huì)引起程序crash掉。
2.
了解到1中assign的問(wèn)題丽蝎,那么如何解決猎拨?最簡(jiǎn)單的一個(gè)方法就是使用引用計(jì)數(shù)(reference
counting),還是上面的那個(gè)例子屠阻,我們給那塊內(nèi)存設(shè)一個(gè)引用計(jì)數(shù)红省,當(dāng)內(nèi)存被分配并且賦值給a時(shí),引用計(jì)數(shù)是1国觉。當(dāng)把a(bǔ)賦值給b時(shí)引用計(jì)數(shù)增加到
2吧恃。這時(shí)如果a不再使用這塊內(nèi)存,它只需要把引用計(jì)數(shù)減1麻诀,表明自己不再擁有這塊內(nèi)存痕寓。b不再使用這塊內(nèi)存時(shí)也把引用計(jì)數(shù)減1。當(dāng)引用計(jì)數(shù)變?yōu)?的時(shí)候蝇闭,
代表該內(nèi)存不再被任何指針?biāo)蒙肼剩到y(tǒng)可以把它直接釋放掉。
3. 上面兩點(diǎn)其實(shí)就是assign和retain的區(qū)別呻引,assign就是直接賦值礼仗,從而可能引起1中的問(wèn)題,當(dāng)數(shù)據(jù)為int, float等原生類型時(shí),可以使用assign藐守。retain就如2中所述挪丢,使用了引用計(jì)數(shù),retain引起引用計(jì)數(shù)加1,release引起引用計(jì)數(shù)減1卢厂,當(dāng)引用計(jì)數(shù)為0時(shí)乾蓬,dealloc函數(shù)被調(diào)用,內(nèi)存被回收慎恒。
4.copy是在你不希望a和b共享一塊內(nèi)存時(shí)會(huì)使用到任内。a和b各自有自己的內(nèi)存。
5. atomic和nonatomic用來(lái)決定編譯器生成的getter和setter是否為原子操作融柬。在多線程環(huán)境下死嗦,原子操作是必要的,否則有可能引起錯(cuò)誤的結(jié)果粒氧。加了atomic越除,setter函數(shù)會(huì)變成下面這樣:
if?(property?!=?newValue)?{
[property?release];
property?=?[newValue?retain];
}
二,深入理解一下(包括autorelease)1. retain之后count加一。alloc之后count就是1外盯,release就會(huì)調(diào)用dealloc銷毀這個(gè)對(duì)象摘盆。
如果 retain,需要release兩次饱苟。通常在method中把參數(shù)賦給成員變量時(shí)需要retain孩擂。
例如:
ClassA有 setName這個(gè)方法:
-(void)setName:(ClassName *) inputName
{
name = inputName;
[name retain]; //此處retian,等同于[inputName retain],count等于2
}
調(diào)用時(shí):
ClassName *myName = [[ClassName alloc] init];
[classA setName:myName]; //retain count == 2
[myName release]; //retain count==1箱熬,在ClassA的dealloc中release name才能真正釋放內(nèi)存类垦。
2. autorelease 更加tricky,而且很容易被它的名字迷惑城须。我在這里要強(qiáng)調(diào)一下:autorelease不是garbage collection蚤认,完全不同于Java或者.Net中的GC。
autorelease和作用域沒(méi)有任何關(guān)系糕伐!
autorelease 原理:
a.先建立一個(gè)autorelease pool
b.對(duì)象從這個(gè)autorelease pool里面生成砰琢。
c.對(duì)象生成 之后調(diào)用autorelease函數(shù),這個(gè)函數(shù)的作用僅僅是在autorelease pool中做個(gè)標(biāo)記赤炒,讓pool記得將來(lái)release一下這個(gè)對(duì)象氯析。
d.程序結(jié)束時(shí)亏较,pool本身也需要rerlease, 此時(shí)pool會(huì)把每一個(gè)標(biāo)記為autorelease的對(duì)象release一次莺褒。如果某個(gè)對(duì)象此時(shí)retain count大于1,這個(gè)對(duì)象還是沒(méi)有被銷毀雪情。
上面這個(gè)例子應(yīng)該這樣寫:
ClassName *myName = [[[ClassName alloc] init] autorelease];//標(biāo)記為autorelease
[classA setName:myName]; //retain count == 2
[myName release]; //retain count==1遵岩,注意,在ClassA的dealloc中不能release name,否則release pool時(shí)會(huì)release這個(gè)retain count為0的對(duì)象尘执,這是不對(duì)的舍哄。
記住一點(diǎn):如果這個(gè)對(duì)象是你alloc或者new出來(lái)的,你就需要調(diào)用release誊锭。如果使用autorelease表悬,那么僅在發(fā)生過(guò)retain的時(shí)候release一次(讓retain count始終為1)。
3 xcode 中的新標(biāo)記?strong weak
strong 用來(lái)修飾強(qiáng)引用的屬性丧靡;對(duì)應(yīng)以前retain
weak 用來(lái)修飾弱引用的屬性蟆沫;對(duì)應(yīng)以前的assign
=================================
何時(shí)使用的問(wèn)題,如果一個(gè)對(duì)象在某段時(shí)間中反復(fù)加載温治,而你又不希望每次加載都要重新alloc 的話饭庞,那就strong,strong 保證對(duì)此對(duì)象保持一個(gè)強(qiáng)引用熬荆,對(duì)于這個(gè)對(duì)象舟山,只要有1個(gè)strong引用的話,那它就不會(huì)釋放卤恳,當(dāng)然多個(gè)strong同時(shí)作用于它也不會(huì)釋放累盗。
如果一個(gè)對(duì)象在某段時(shí)間只會(huì)加載一次,并且加載之后確定不再使用了纬黎,那就可以使用weak,這樣當(dāng)其他原因?qū)е乱糜?jì)數(shù)減1(比如 removefromsuperview)的時(shí)候幅骄,此對(duì)象就自動(dòng)釋放了。無(wú)需再在delloc 里面再release一次本今,但你要保證釋放之后確實(shí)不再使用此對(duì)象拆座,否則將導(dǎo)致錯(cuò)誤
NSString類用COPY,控件類用WEAk,冠息,復(fù)雜數(shù)據(jù)類的用STRONG挪凑,數(shù)字類,比如INUIgter逛艰,nsinter躏碳,cgreck這些用ASSAGIN