了解Xcode 4.2中Automatic Reference Counting(ARC)
了解Xcode 4.2中Automatic Reference Counting (ARC)是本文要講解的內(nèi)容,Automatic Reference Counting (ARC),自動(dòng)引用計(jì)數(shù),是開發(fā)Cocoa程序時(shí)的一個(gè)編譯級(jí)別的特性,用于自動(dòng)內(nèi)存管理。
在XCode 4.2中,使用模板新建一個(gè)工程,該工程將使用ARC特性。
如果你的iOS SDK是iOS5 seed release 2,需要做如下修改,才能避免編譯時(shí)的錯(cuò)誤:
- 在
- System/Library/Frameworks/CoreFoundation.framework /Headers/CFBase.h
- 中,將:
- CFTypeRef CFMakeCollectable(CFTypeRef cf) CF_AUTOMATED_REFCOUNT_UNAVAILABLE;
修改成:
- CFTypeRef CFMakeCollectable(CFTypeRef cf);
- 在System/Library/Frameworks/Foundation.framework/Hea ders/NSObject.h中,將:
- return (__bridge_retain CFTypeRef)X;
修改成:
- return (__bridge_retained CFTypeRef)X;
使用ARC將讓你遠(yuǎn)離煩人且容易遺漏的retain,release和autorelease等操作。
ARC的工作原理是,在你編譯程序時(shí),將內(nèi)存操作的代碼(retain,release或autorelease)自動(dòng)添加到需要的位置。即底層上使用和Manual Reference Counting(手工引用計(jì)數(shù))一樣的內(nèi)存管理機(jī)制,但由于XCode自動(dòng)幫你在編譯時(shí)添加內(nèi)存操作的代碼,從而簡化了編程的工作。
啟用ARC,編譯選項(xiàng)中需加上-fobjc-arc,不過這個(gè)由XCode在創(chuàng)建工程模板時(shí)幫你完成。
XCode 4.2以前版本都不支持ARC。
對(duì)操作系統(tǒng)也有要求:Mac OS X v10.6或v10.7 (64-bit applications),iOS4或iOS5。注意:其中Mac OS X v10.6和iOS4不支持weak references(弱引用,后面會(huì)說明什么是weak references)。
Xcode 4.2提供了一個(gè)名為“Convert to Objective-C Automatic Reference Counting”的工具,在Edit->Convert menu下,可以幫你自動(dòng)將使用Manual Reference Counting的老代碼轉(zhuǎn)換成使用ARC的新代碼(例如去掉對(duì)retain和release的調(diào)用)。
一個(gè)使用ARC的代碼例子:
- @interface Person : NSObject
- @property (nonatomic, strong) NSString *firstName;
- @property (nonatomic, strong) NSString *lastName;
- @property (nonatomic, strong) NSNumber *yearOfBirth;
- @property (nonatomic, strong) Person *spouse;
- @end
- @implementation Person
- @synthesize firstName, lastName, yearOfBirth, spouse; @end
注意:不再需要重載dealloc函數(shù),因?yàn)闆]有release操作。(strong的語義后面會(huì)介紹。)
例子2:
- (void)contrived { Person *aPerson = [[Person alloc] init];
- [aPerson setFirstName:@"William"];
- [aPerson setLastName:@"Dudney"];
- [aPerson:setYearOfBirth:[[NSNumber alloc] initWithInteger:2011]];
- NSLog(@"aPerson: %@", aPerson);
- }
注意:沒有了release操作。
例子3: (void)takeLastNameFrom:(Person *)person { NSString *oldLastname = [self lastName]; [self setLastName:[person lastName]]; NSLog(@"Lastname changed from %@ to %@", oldLastname, [self lastName]); } 注意:ARC會(huì)保證oldLastname引用的對(duì)象在NSLog執(zhí)行結(jié)束之前,不會(huì)被釋放掉。
使用ARC的一些規(guī)則: 不能直接調(diào)用dealloc方法,不能重載或直接調(diào)用retain,release,retainCount,或autorelease等方法。
但可以通過@selector(retain),@selector(release)這樣的形式調(diào)用。
用戶自定義的dealloc方法,不能調(diào)用[super dealloc],編譯器會(huì)自動(dòng)幫你添加這個(gè)代碼。
對(duì)Core Foundation-style的對(duì)象,仍可以使用CFRetain, CFRelease等方法。 不能使用NSAllocateObject或NSDeallocateObject去創(chuàng)建對(duì)象,請使用alloc方法。 在c語言中的結(jié)構(gòu)體中,不能再使用對(duì)象指針。請放棄C結(jié)構(gòu)體,使用Objective-C的類。 id和void*之間沒有隱式的類型轉(zhuǎn)換,請使用顯式類型轉(zhuǎn)換。 不能使用NSAutoreleasePool,ARC提供了@autoreleasepool語句塊。
例如:
- @autoreleasepool {
- // Code, such as a loop that creates a large number of temporary objects.
- }
不能使用NSZone。 方法和變量的命名不能以“new”開頭。 關(guān)于對(duì)象的生命周期: weak引用:設(shè)置成weak的屬性,不會(huì)影響對(duì)象的生命周期,如果引用的對(duì)象已經(jīng)被釋放,引用會(huì)指向nil。 strong引用:設(shè)置成strong的屬性,會(huì)影響對(duì)象的生命周期。 例如:
- @property(strong) MyClass *myObject; 和@property(retain) MyClass *myObject;是等效的。
又例如:
- @property(weak) MyClass *myObject;和@property(assign) MyClass *myObject;
在多數(shù)情況下等效,但當(dāng)instance被釋放時(shí),設(shè)置為weak的引用會(huì)指向nil。
可用的限定詞: __strong, 默認(rèn)的 __weak __unsafe_unretained,和weak的區(qū)別是當(dāng)對(duì)象被釋放時(shí),引用不指向nil。 __autoreleasing,當(dāng)方法的參數(shù)是id*,且希望方法返回時(shí)對(duì)象被autoreleased,可以添加__autoreleasing限定詞。 使用__weak時(shí)要特別小心,例如
- NSString __weak *string = [[NSString alloc] initWithFormat:@"First Name: %@", [self firstName]];
- NSLog(@"string: %@", string); //此時(shí)string為空,因?yàn)閣eak類型不影響對(duì)象的生命周期,對(duì)象剛創(chuàng)建就釋放了。
其他特性: 使用strong, weak, autoreleasing限定的變量會(huì)被隱式初始化為nil。
例如:
- - (void)myMethod { NSString *name; NSLog(@"name: %@", name); //會(huì)輸出null
- }
歡迎大家補(bǔ)充和找bug。
小結(jié):了解Xcode 4.2中Automatic Reference Counting (ARC)的內(nèi)容介紹完了,希望通過本文的學(xué)習(xí),能對(duì)你有所幫助!