Xcode 4.2 中的Automatic Reference Counting (ARC)轉

Automatic Reference Counting (ARC), 自動引用計數,是開發Cocoa程序時的一個編譯級別的特性,用於自動內存管理。


XCode 4.2中,使用模板新建一個工程,該工程將使用ARC特性。


如果你的iOS SDKiOS5 seed release 2,需要做如下修改,才能避免編譯時的錯誤:

 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/Headers/NSObject.h, :

return (__bridge_retain CFTypeRef)X;

修改成:

return (__bridge_retained CFTypeRef)X;


使用ARC將讓你遠離煩人且容易遺漏的retainreleaseautorelease等操作。


ARC的工作原理是,在你編譯程序時,將內存操作的代碼(retainreleaseautorelease)自動添加到需要的位置。即底層上使用和Manual Reference Counting(手工引用計數)一樣的內存管理機制,但由於XCode自動幫你在編譯時添加內存操作的代碼,從而簡化了編程的工作。


啓用ARC,編譯選項中需加上-fobjc-arc,不過這個由XCode在創建工程模板時幫你完成。


4.2以前版本的XCode都不支持ARC

對操作系統也有要求:Mac OS X v10.6  v10.7 (64-bit applications) iOS4iOS5。注意:其中Mac OS X v10.6iOS4不支持weak references(弱引用,後面會說明什麼是weak references)


Xcode 4.2提供了一個名爲“Convert to Objective-C Automatic Reference Counting”的工具,在Edit->Convert menu下,可以幫你自動將使用Manual Reference Counting的老代碼轉換成使用ARC的新代碼(例如去掉對retainrelease的調用)。


一個使用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函數,因爲沒有release操作。(strong的語義後面會介紹。


例子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會保證 oldLastname引用的對象在NSLog執行結束之前,不會被釋放掉。


使用ARC的一些規則:

  • 不能直接調用dealloc方法,不能重載或直接調用retain, release, retainCount,  autorelease等方法。

    但可以通過@selector(retain), @selector(release)這樣的形式調用。

    用戶自定義的dealloc方法,不能調用[super dealloc] ,編譯器會自動幫你添加這個代碼。

    Core Foundation-style 的對象,仍可以使用CFRetain, CFRelease等方法。

  • 不能使用NSAllocateObjectNSDeallocateObject去創建對象,請使用alloc方法。

  • c語言中的結構體中,不能再使用對象指針。請放棄C結構體,使用Objective-C的類。

  • idvoid*之間沒有隱式的類型轉換,請使用顯式類型轉換。

  • 不能使用NSAutoreleasePoolARC提供了@autoreleasepool語句塊。

    例如:

    @autoreleasepool {

    // Code, such as a loop that creates a large number of temporary objects.

}

  • 不能使用NSZone

  • 方法和變量的命名不能以“new”開頭。


關於對象的生命週期:

  • weak引用:設置成weak的屬性,不會影響對象的生命週期,如果引用的對象已經被釋放,引用會指向nil

  • strong引用:設置成strong的屬性,會影響對象的生命週期。

例如:

@property(strong) MyClass *myObject;  @property(retain) MyClass *myObject; 是等效的。


又例如:

@property(weak) MyClass *myObject;  @property(assign) MyClass *myObject; 在多數情況下等效,但當instance被釋放時,設置爲weak的引用會指向nil


可用的限定詞:

  • __strong, 默認的

  • __weak

  • __unsafe_unretained, 和weak的區別是當對象被釋放時,引用不指向nil

  • __autoreleasing,當方法的參數是id*,且希望方法返回時對象被autoreleased,可以添加__autoreleasing限定詞。


使用__weak時要特別小心,例如

NSString __weak *string = [[NSString alloc] initWithFormat:@"First Name: %@", [self firstName]];

NSLog(@"string: %@", string); //此時 string爲空,因爲weak類型不影響對象的生命週期,對象剛創建就釋放了。


其他特性:

  • 使用strong, weak, autoreleasing限定的變量會被隱式初始化爲nil

    例如:

    - (void)myMethod { NSString *name;

NSLog(@"name: %@", name); //會輸出null

}


另,歡迎大家補充和找bug。



 原文地址:http://blog.sina.com.cn/s/blog_4c4c79950100t3uy.html

發佈了30 篇原創文章 · 獲贊 6 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章