您好,登錄后才能下訂單哦!
自動(dòng)引用計(jì)數(shù)
上面的那樣處理過(guò)程,使得問(wèn)題變得更加復(fù)雜,因?yàn)槟憧偸且涀?nèi)存管理的規(guī)則,你需要知道什么時(shí)候在代碼中加入retain,release,或者autorelease。因此,在新版Xcode(Xcode4.2),蘋果發(fā)布了一個(gè)新的機(jī)制,使得retain,release,和autorelease自動(dòng)執(zhí)行。上面所有的策略依然可以應(yīng)用在新版本的代碼中。但是Xcode會(huì)為你添加內(nèi)存管理需要的代碼。
為了給你一個(gè)快速的了解,我重新編寫Listing 7.1和Listing 7.2代碼。
Listing 7.4. Rewrite Code for the New ARC mechanism
For Listing 7.1:
- (void)doSomething {
NSObject *obj = [[NSObject alloc] init];
NSLog(@"obj: %@", obj);
}
For Listing 7.3:
- (NSObject *)getObj {
NSObject *obj = [[NSObject alloc] init];
return obj;
}
就是這樣!不在需要release或autorelease。當(dāng)你編譯代碼的時(shí)候,Xcode會(huì)自動(dòng)的為你添加release/autorelease相關(guān)代碼。在編譯器添加這些調(diào)用后,代碼就和Listing 7.1和Listing 7.3一樣了。
如何在Xcode中設(shè)置你的工程?
進(jìn)入你的工程的settings,查找Objective-C Automatic ReferenceCounting是否設(shè)置為YES。你可以在圖7-2的看到設(shè)置行的位置:
如果有一個(gè)已經(jīng)使用了retain/release/autorelease的工程,你可以使用Xcode的migration工具來(lái)刪除這些不需要的代碼,如圖7-3 。
ARC策略
你需要遵守一些新的規(guī)則來(lái)確保你的工程兼容ARC:
你不能使用或調(diào)用舊的內(nèi)存管理方法:retain,release,autorelease和retainCount。你可以復(fù)寫dealloc方法做任何你需要清理的工作,但是你不能調(diào)用dealloc方法,例如[super dealloc]是不允許的。
在構(gòu)建屬性的時(shí)候,這個(gè)規(guī)則也是強(qiáng)制要求的:
@property (nonatomic, retain) NSString *myName; // 這是不允許的
在c中不能使用對(duì)象指針,這會(huì)導(dǎo)致很多問(wèn)題,如果你想在你的工程中集成c代碼,如第9章所描述。你不能使用NSAutoreleasePool對(duì)象,必須使用@autoreleasepool。
不能使用:
NSAutoreleasePool *myPool = [[NSAutoreleasePool alloc] init];
// your code here
[pool release];
必須使用:
@autoreleasepool {
// your code here
}
ARC新的修飾符
根據(jù)新的ARC策略,你現(xiàn)在需要包含新的生命周期的修飾符來(lái)運(yùn)用新的ARC規(guī)則。
strong:這個(gè)表示你想保持一個(gè)變量的強(qiáng)引用。只要有對(duì)象A的一個(gè)強(qiáng)引用,對(duì)象A就不會(huì)deallocated。
weak:這個(gè)和assign類似,如果你只是想要保持一個(gè)對(duì)象的引用,而又不想顯示的擁有它。因此,你不需要管理這個(gè)對(duì)象的生命周期。一個(gè)比較好的情況是:如果對(duì)象A有對(duì)象B的一個(gè)弱引用,如果對(duì)象B被deallocated,那么這個(gè)引用會(huì)變成nil。這樣是比較安全的,因?yàn)槟悴粫?huì)擁有一個(gè)已經(jīng)deallocated對(duì)象的引用。
unsafe_unretained:這個(gè)和weak類似,他們的不同之處是:對(duì)象A有對(duì)象B的一個(gè)引用,如果對(duì)象B被deallocated了,那么對(duì)象A的引用就會(huì)指向一個(gè)deallocated對(duì)象,這樣會(huì)導(dǎo)致應(yīng)用程序崩潰。
autoreleaseing:如果你有一個(gè)方法需要引用傳遞的參數(shù),你可以考慮這個(gè)修飾符。當(dāng)返回的時(shí)候,方法會(huì)負(fù)責(zé)autorelease這個(gè)參數(shù)。
對(duì)象屬性
現(xiàn)在,你需要改變對(duì)象屬性的聲明。不要在使用之前版本的舊的內(nèi)存管理機(jī)制:@property (retain) NSString *myString,現(xiàn)在有一個(gè)新的規(guī)則。
如果你想擁有一個(gè)對(duì)象的所有權(quán)
// This is similar to @property (retain) NSString *myString
@property(strong) NSString *myString;
如果你只是要持有一個(gè)對(duì)象的引用,而不是它的所有權(quán)
// This is similar to @property (assign) UIViewController *myViewController;
// except that if myViewController object is deallocated,
// the reference becomes nil.
@property(weak) UIViewController*myString;
注意:如果你想要你的應(yīng)用運(yùn)行在iOS4,你不能使用weak。你需要使用unsafe_unretained然后自己設(shè)置引用為nil。 |
變量聲明
為了在方法內(nèi)部使用這些修飾符,你需要在它的前面添加__(兩個(gè)下劃線)。例如,你可以使用__strong或__weak。在方法中,__strong是默認(rèn)的修飾符。
使用__strong修飾符能確保你的對(duì)象一直存在直到方法結(jié)束,同時(shí)要小心使用__weak或__unsafe_unretained。如果沒(méi)有強(qiáng)引用指向你的對(duì)象,你的對(duì)象會(huì)立即崩潰。例如:
NSString __weak *myString = @"hello world";
NSLog (@"myString: %@", myString);
將會(huì)打印(null),因?yàn)樵诖蛴r(shí),已經(jīng)沒(méi)有強(qiáng)引用指向它。
__autoreleasing修飾符用來(lái)給方法接收一個(gè)引用傳遞的參數(shù)。
- (BOOL)performTaskWithError:(NSError *__autoreleasing *)error;
你可以正常的調(diào)用它:
NSError *error = nil;
[self performTaskWithError:&error];
默認(rèn),error對(duì)象聲明為強(qiáng)引用,但是編譯器會(huì)添加代碼使得調(diào)用方法[self performTaskWithError:&error] ;
注意:對(duì)于返回對(duì)象的所有方法,同時(shí)沒(méi)有包含new,alloc或copy,對(duì)象在返回是會(huì)自動(dòng)的變?yōu)閍utoreleased。 |
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。