自動引用計數(ARC)是編譯器的一個特點,提供了Objective-C對象的自動內存管理機制。比起不得不考慮retain和release操做,ARC讓你更加專一於應用中那些有趣的代碼,如對象圖,對象關係。
摘要(Summary)
經過在編譯期添加代碼的方式,ARC保證全部對象按需存在,按需釋放。從概念上來說,它與手動引用計數(參見
Advanced Memory Management Programming Guide)有着相同的內存管理約定,兩者都會爲你添加合適的內存管理方法調用。
爲了編譯器能生成正確的代碼,ARC限定了你可使用的一些方法,以及toll-free橋接的使用方式(參見
「Toll-Free Bridged Types」).與此同時ARC還爲對象引用(object references )和聲明式屬性(declared properties)引進了新的生命週期限定符(lifetime qualifiers )。
ARC適用於OS X v10.6和v10.7(64位)下的Xcode4.2,以及IOS 4和IOS5.OS X v10.6和IOS4不支持弱引用。
Xcode提供了自動化的工具,完成ARC轉換過程當中須要手工操做的部分(例如刪除retain和release方法調用),而且幫助你在遷移過程當中不能自動完成的操做(選擇Edit->Refactor->Convert to Objective-C ARC)。遷移工具將工程中的全部文件使用ARC進行轉換。若是你以爲在某些文件中使用手動引用計數會更方便,那麼你也能夠選擇在單獨文件中使用ARC。
參見:
Advanced Memory Management Programming Guide
Memory Management Programming Guide for Core Foundation
ARC概述(ARC Overview)
ARC會評估對象所需的生命期,並會在編譯期爲你自動插入合適的內存管理調用方法,取代以前你不得不考慮什麼時候須要使用
retain,
release以及
autorelease的操做方式。編譯器也會爲你生成合適的
dealloc方法。總的來講,若是你僅使用ARC,傳統的Cocoa命名規範只會在你須要與使用手動引用計數的代碼交互時纔是重要的。
一個完整正確的
Person類的實現看起來多是這樣的:
@interface Person : NSObject
@property NSString *firstName;
@property NSString *lastName;
@property NSNumber *yearOfBirth;
@property Person *spouse;
@end
@implementation Person
@end
(對象屬性(properties)默認是強類型的(
strong);
strong屬性描述於
「ARC Introduces New Lifetime Qualifiers.」)
使用ARC,你能夠以下實現一個
contrived方法:
- (void)contrived
{
Person *aPerson = [[Person alloc] init];
[aPerson setFirstName:@"William"];
[aPerson setLastName:@"Dudney"];
[aPerson setYearOfBirth:[[NSNumber alloc] initWithInteger:2011]];
NSLog(@"aPerson: %@", aPerson);
}
ARC會維護內存管理,因此
Person和
NSNumber對象都不會泄露。
你也能夠安全的實現
Person類中的
takeLastnameFrom:方法。
- (void)takeLastNameFrom:(Person *)person {
NSString *oldLastname = [self lastName];
[self setLastName:[person lastName]];
NSLog(@"Lastname changed from %@ to %@", oldLastname, [self lastName]);
}
ARC保證
oldLastName在
NSLog語句以前不會被釋放。
【ARC強制執行新規則】(ARC Enforces New Rules)
爲了正常運轉,ARC使用了一些在使用其它編譯模式下沒有的新規則。這些規則意在提供徹底可靠的內存管理模型;在某些狀況下,它們僅使用最佳實踐方法,在其它狀況下,它們僅簡化你的代碼或明顯的作出推論告知你不須要處理內存管理。若是
你違反了這些規則,你會立刻獲得一個編譯期錯誤,而不是在運行期可能會顯現的一個狡猾的bug。
1.不能顯示的調用dealloc,實現或調用
retain,
release,
retainCount,或
autorelease。
一樣也不要能使用
@selector(retain),
@selector(release), 等等相似的選擇器。
若是你須要管理資源而不是釋放實例變量,那你能夠實現
dealloc方法。你不須要(事實上你不能)釋放實例變量,但你可能須要在系統類和其它的未使用ARC代碼中調用
[systemClassInstance setDelegate:nil] 方法。
在ARC中自定義的
dealloc方法不要調用
[super dealloc]方法(它實際上會致使編譯器錯誤)。到super的鏈式調用是自動的而且是編譯器強制執行的。
你仍能夠在Core Foundation樣式的的對象上,使用
CFRetain,
CFRelease,和其它相關的函數。
2.你不能使用
NSAllocateObject 或
NSDeallocateObject
你使用
alloc來建立對象;運行時系統會注意釋放這些對象。
3.你不能在C語言結構體中使用對象指針。
與其使用一個結構體(
struct),不如建立一個Objective-C類來管理數據。
4.
id與
void*之間不能隨意轉換
你必須使用特定的類型轉換來告訴編譯器對象的生命週期。你須要在Objective-C對象和以函數參數傳入的Core Foundation類型值之間進行這樣的轉換。有關詳情,參見
「Managing Toll-Free Bridging」。
5.你不能使用
NSAutoreleasePool對象
ARC 提供了
@autoreleasepool來代替。這比
NSAutoreleasePool更高效。
6.你不能使用內存區(memory zones)。
再也沒有使用
NSZone的必要了——現代的Obj-C運行時會永遠忽略它。
爲了容許與自動retain-release的代碼進行交互,ARC在方法命名上加上了一個約束:
你不能以
new爲開頭命名一個訪問器的名字。這反過來意味着你沒必要聲明一個以new開頭的屬性,除非你指定一個不一樣名稱的getter方法:
// Won't work:
@property NSString *newTitle;
// Works:
@property (getter=theNewTitle) NSString *newTitle;
【ARC引入新的生命週期限定符】(ARC Introduces New Lifetime Qualifiers)
ARC爲對象引入了幾種新的生命週期限定符,以及弱類型引用(
weak references)。弱類型應用不會延長它所指向對象的生命週期,一旦對象沒有強引用指向對象時,弱引用會自動變爲
nil。
在程序中,你應該充分利用這些限定符來管理對象圖。尤爲是,ARC不能阻止強引用循環(strong reference cycles,以前稱爲retain cycles,參見「Practical Memory Management」)的發生。審慎的使用弱類型關係會幫助你避免建立強引用循環。
【Property的屬性】(Property Attributes)
weak和
strong關鍵字是新引入的property聲明屬性,以下例所示:
// 如下聲明等價於 @property(retain) MyClass *myObject;
@property(strong) MyClass *myObject;
// 如下聲明等價於"@property(assign) MyClass *myObject;"
// 不一樣之處在於若是MyClass的實例變量釋放時,其屬性值會設置爲nil,而不會保存爲一個野指針
@property(weak) MyClass *myObject;
ARC下,對象類型的聲明默認爲
strong
【變量限定符】(Variable Qualifiers)
你能夠向使用其它變量的限定符那樣,好比說,
const,來使用如下生命週期限定符,
__strong
__weak
__unsafe_unretained
__autoreleasing
__strong是默認的。只要有強類型指針指向一個對象,那麼該對象會一直」生存「下去。
__weak代表一個不會維持所持對象生命期的引用。當沒有強引用指向該對象時,弱引用會設置爲nil。
__unsafe_unretained指定一個引用,該引用不會維持所持對象的生命期,而且在沒有強引用指向對象時也不會設置爲nil。若是它所指向的對象已經被釋放,那麼它會成爲一個野指針。
__autoreleasing 用以指示以引用(id*)傳入的參數並在retun後自動釋放。
你應該正確的修飾變量。在對象變量的聲明時使用限定符的正確格式爲:
ClassName * qualifier variableName;
例如:
MyClass * __weak myWeakReference;
MyClass * __unsafe_unretained myUnsafeReference;
從技術上講其它的變體寫法都是錯誤的,但編譯器都會」寬恕「它們。要弄清該問題,參見http://cdecl.org/.
在堆棧上使用
__weak變量時要小心。考慮如下的例子:
NSString * __weak string = [[NSString alloc] initWithFormat:@"First Name: %@", [self firstName]];
NSLog(@"string: %@", string);
雖然
string是在初始化賦值以後使用,可是在賦值的時候並無其它強引用指向字符串對象;所以字符串對象會立刻釋放掉。log語句顯示
stirng的值爲
null。(編譯器對這種狀況會提示警告)
你也要注意經過引用方式傳入的對象。如下代碼會正常運轉
NSError *error;
BOOL OK = [myObject performOperationWithError:&error];
if (!OK) {
// Report the error.
// ...
而error的聲明是隱式的:
NSError * __strong e;
方法的聲明一般是:
-(BOOL)performOperationWithError:(NSError * __autoreleasing *)error;
所以編譯器會重寫代碼:
NSError * __strong error;
NSError * __autoreleasing tmp = error;
BOOL OK = [myObject performOperationWithError:&tmp];
error = tmp;
if (!OK) {
// Report the error.
// ...
本地變量聲明(
__strong)和參數(
__autoreleasing)之間的區別致使編譯器建立臨時變量。在獲取__strong變量的地址時你能夠經過將參數聲明爲
id __storng*來得到其原始指針。或者你能夠將變量聲明爲
__autoreleasing。
【使用生命週期限定符來避免強類型循環引用】(Use Lifetime Qualifiers to Avoid Strong Reference Cycles)
你可使用生命週期限定符來避免強類型循環引用。例如,一般若是你的對象圖造成於父-子層級結構中,父對象須要引用它的子對象,反之亦然,那麼你構造parent-to-child的關係爲強類型,child-to-parent的關係爲弱類型。其它狀況可能會更加微妙,尤爲是在涉及到block對象時。
在手動引用技術的模式下,
__block id x,不會保留x。在ARC模式下,
__block id x;默認會保留x(就像其它值同樣)。爲了在ARC下達到手動引用技術的效果,你可使用
__unsafe__unretained __block id x ;然而,就像
__unsafe_unretained名字蘊含的那樣,擁有一個未保留變量(non-retained variable)是危險的(由於他多是一個野指針),所以最好不要使用。有兩個更好的選擇是要麼使用
__weak(若是你不須要支持IOS4或OS X v10.6),要門設置
__block值nil來打破循環引用。
如下的代碼片斷說明了在手動引用技術下時常會使用的模式。
MyViewController *myController = [[MyViewController alloc] init…];
// ...
myController.completionHandler = ^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
};
[self presentViewController:myController animated:YES completion:^{
[myController release];
}];
如上所屬,你可使用
__block限定符來替代,並在
completion處理方法中將myController的值設置爲nil:
MyViewController * __block myController = [[MyViewController alloc] init…];
// ...
myController.completionHandler = ^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
myController = nil;
};
或者,你可使用一個臨時的
__weak變量。如下代碼列舉了一個簡單的實現:
MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyViewController = myController;
myController.completionHandler = ^(NSInteger result) {
[weakMyViewController dismissViewControllerAnimated:YES completion:nil];
};
而對於特殊的循環,你應該使用:
MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyController = myController;
myController.completionHandler = ^(NSInteger result) {
MyViewController *strongMyController = weakMyController;
if (strongMyController) {
// ...
[strongMyController dismissViewControllerAnimated:YES completion:nil];
// ...
}
else {
// Probably nothing...
}
};
某些狀況下若是一個類不兼容__
weak,你可使用
__unsafe_unretained。但這也不適用於特殊的循環,由於在實際問題中驗證
__unsafe_unretained指針是否仍有效或是否仍指向相同的對象,是很是困難或根本不可能實現的。
【ARC使用新聲明來管理自動釋放池】(ARC Uses a New Statement to Manage Autorelease Pools)
使用ARC,你不能直接使用NSAutoreleasePool類來管理自動釋放池。相反,你須要使用
@autoreleasepool塊:
@autoreleasepool {
// Code, such as a loop that creates a large number of temporary objects.
}
這個簡單的結構讓編譯器來判斷引用計數的狀態。在入口,自動釋放池會被push。在正常退出(
break,return,goto,fall-through,dengd)自動釋放池會被pop。出於對已有代碼兼容性的考慮,若是因異常致使退出,自動釋放池將不會被pop。
該語法在全部Objecti-C模式下均可用。相比使用
NSAutoreleasePool類來講,
@autoreleasepool更加高效;所以鼓勵你在使用
NSAutoreleasePool的地方使用
@autoreleasepool。
【跨平臺下Outlets管理保持一致的模式】(Patterns for Managing Outlets Become Consistent Across Platforms)
ARC下的IOS和OS X中聲明outlets的模式已經發生變化,而且在跨平臺下保持一致性。你一般應該接受的是:outlets應該是
weak的,除了那些在nib文件(或storyboard屏)中File‘s Owner指向的頂級對象應該是
strong的。
Resource Programming Guide.中的
」Nib Files「作出了全面的解釋。
【堆變量會初始化爲nil】(Stack Variables Are Initialized with nil)
使用ARC,strong,weak,以及autoreleasing的堆變量如今會隱式的初始化爲nil,例如:
- (void)myMethod {
NSString *name;
NSLog(@"name: %@", name);
}
輸出的
name的值爲null而不多是程序崩潰。
【使用編譯器指令來啓用或禁用ARC】(Use Compiler Flags to Enable and Disable ARC)
使用
-fobjc-arc編譯指令來啓動ARC。若是在某些文件中使用手動引用技術對你來講更方便些,你能夠選擇在單獨的文件上使用ARC。對於默認使用ARC的工程,你可使用
fno-objc-arc編譯指令來禁用某個文件的ARC。
Xcode4.2及更高版本,OS X v10.6及更高版本(64爲應用),IOS4版本或更高版本支持ARC。OS X v10.6和IOS4不支持弱引用。Xcode4.1及早期版本的Xcode不支持ARC。
【管理Toll-Free橋接】(Managing Toll-Free Bridging)
在許多Cocoa應用中,你可使用Core Foundation樣式的對象,不論是來自於Core Foundation框架自己(例如,
CFArrayRef 或
CFMutableDictionaryRef),仍是來自於諸如Core Graphics同樣採用Core Foundation約定的框架(你可能使用向
CGColorSpaceRef and
CGGradientRef樣式的類型)。
編譯器不會自動管理Core Foundation對象的生命週期;你必須調用符合Core Founda內存管理規則的CFRetain和CFRelease方法(或者合適的特殊類型變體)來釋放對象。(參見
Memory Management Programming Guide for Core Foundation)
若是你在Objective-C對象和Core Foundation樣式對象間執行類型轉換,你要告訴編譯器對象的歸屬語義,無論對象是使用類型轉換(定義在objc/runtime.h)或Core Foundation樣式的宏(定義在NSObject.h)。
__bridge在Objective-C和Core Foundation間的指針轉換不附加對象的全部權。
__bridge_retained或
CFBridgingRetain將Objectiv-C指針轉換爲Core Foundation指針,而且將對象的全部權轉給你。你負責調用CFRelease或相關的函數來放棄對象的全部權。
__bridge_transfer或
CFBridgingRelease將一個非Objective-C指針轉移到Objective-C指針,並將對象全部權轉交給ARC。ARC負責放棄對象的全部權。
例如,若是你有這樣的代碼:
- (void)logFirstNameOfPerson:(ABRecordRef)person {
NSString *name = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSLog(@"Person's first name: %@", name);
[name release];
}
你應該替代爲:
- (void)logFirstNameOfPerson:(ABRecordRef)person {
NSString *name = (NSString *)CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
NSLog(@"Person's first name: %@", name);
}
【編譯器處理Cocoa方法返回的CF對象】(The Compiler Handles CF Objects Returned From Cocoa Methods)
編譯器瞭解Objective-C的那些沿用Cocoa命名規則返回Core Foundation類型的方法(參見
Advanced Memory Management Programming Guide)。例如,編譯器知道,在IOS中,
UIColor的
CGColor方法返回的CGColor不會被擁有。你仍需使用合適的類型轉換,以下例所示:
NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]];
[colors addObject:(id)[[UIColor lightGrayColor] CGColor]];
【使用全部權關鍵字對函數參數進行強制類型轉換】(Cast Function Parameters Using Ownership Keywords)
函數調用中在Objective-C和Core Foundation對象之間進行轉換,你要告訴編譯器被傳入的對象的全部權語義。Core Foundation的全部權規則在Core Foundation的內存管理規則中都已近說明了(參見
Memory Management Programming Guide for Core Foundation);Objective-C對象的規則在
Advanced Memory Management Programming Guide.有說明。
在下面的代碼片斷中,傳入
CGGradientCreateWithColors函數的數組須要一個合適的類型轉換。
arrayWithObjects:方法返回的對象的全部權不會傳給函數,所以須要用
__bridge轉換。
NSArray *colors = <#An array of colors#>;
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
如下方法實現中展現了代碼片斷。要注意的是聽從Core Foundation內存管理規則的Core Foundation內存管理函數的用法。
- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGFloat locations[2] = {0.0, 1.0};
NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]];
[colors addObject:(id)[[UIColor lightGrayColor] CGColor]];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
CGColorSpaceRelease(colorSpace); // Release owned Core Foundation object.
CGPoint startPoint = CGPointMake(0.0, 0.0);
CGPoint endPoint = CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMaxY(self.bounds));
CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint,
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
CGGradientRelease(gradient); // Release owned Core Foundation object.
}
【工程轉換時的常見問題】(Common Issues While Converting a Project)
當遷移已有工程時,可能你會遇到許多問題。這裏列舉一些常見問題,以及解決辦法。
1.不能調用
retain,
release,或
autorelease。
這是一個特殊點。你也不能寫:
while ([x retainCount]) { [x release]; }
2.不能調用
dealloc
若是你實現了一個單例對象或在init方法中替換一個對象,你一般會調用
dealloc方法。對於單例對象,使用共享實例模式。在
init方法中,你再也不須要調用dealloc,由於對象在你重寫
self時會被釋放掉。
3.不能使用
NSAutoreleasePool對象
使用新的
@autoreleasepool{}結構代替。這在你的自動釋放池中強制使用block結構,而且比
NSAutoreleasePool要快六倍。即便在非ARC的代碼中
@autoreleasepool也能工做,由於
@autoreleasepool較
NSAutoreleasePool要快得多,因此許多舊的」性能hacks「會無條件的被
@autoreleasepool所替代。
遷移器只處理
NSAutoreleasePool的簡單用法,不能處理複雜條件下的狀況,或者一個定義在新的
@autoreleasepool結構內部的變量並在其以外使用的狀況。
4.ACR須要你將在init方法中
[super init]的結果賦值給
self。
下面的代碼在ARC的init方法中是不合法的:
[super init];
簡單的修正是作以下變換
self = [super init];
更全面的改法是在繼續以前檢測結果是否爲nil:
self = [super init];
if (self) {
...
5.不能實現自定義的
retain和
release方法
實現自定義的
retain和
release方法會打破弱引用。有幾種常見緣由是想要提供提供自定義實現的:
性能
請不要再這麼作了;
NSObject的
retain和
release如今更加快捷。若是你仍發現問題,請提交bug。
實現自定義的弱指針系統
使用
__weak代替
實現單例類
使用共享示例代替。或使用類方法類替代實例方法,這避免了一直都要去分配對象空間的操做。
6."Assigned"實例變量成爲了strong類型
在ARC以前,實例變量是非擁有引用(non-owning redernces)——直接將對象賦值給實例變量不會擴展對象的生命週期。爲了令屬性成爲強類型,你一般只要實現或合成訪問器方法,它們會調用合適的內存管理方法;相比較而言,你可能已經以下例子中實現了訪問器方法來維護一個弱類型屬性。
@interface MyClass : Superclass {
id thing; // Weak reference.
}
// ...
@end
@implementation MyClass
- (id)thing {
return thing;
}
- (void)setThing:(id)newThing {
thing = newThing;
}
// ...
@end
使用ARC,實例變量默認是強類型引用——將實例變量直接賦值給對象的確會擴展對象的生命週期。遷移工具沒辦法決定實例變量什麼時候應該是
weak類型的。爲了像以前那樣維護一樣的行爲,你必須將實例變量標記爲
weak類型,或使用一個聲明式屬性。
@interface MyClass : Superclass {
id __weak thing;
}
// ...
@end
@implementation MyClass
- (id)thing {
return thing;
}
- (void)setThing:(id)newThing {
thing = newThing;
}
// ...
@end
或
@interface MyClass : Superclass
@property (weak) id thing;
// ...
@end
@implementation MyClass
@synthesize thing;
// ...
@end
7.在C語言結構體重不能使用強類型的ids,例如,如下代碼會編譯不過
struct X { id x; float y; };
由於x默認確定是被保留的,編譯器沒法安全的合成全部保證代碼正常運轉所需的全部代碼。例如,若是你經過一些最終會被釋放的代碼來傳入一個指針到這些結構體後,每一個id在結構體回收以前會被被迫釋放掉。編譯器不能可靠的作到這點,因此在結構體中的強類型的ids在ARC模式下是徹底無效的。如下有幾個可能的解決辦法:
1.使用Objective-C對象代替結構體
這是最好的實踐方法。
2.若是使用Objective-C對象是次優方案,(可能你想要這些結構體組成的一個數組)那麼考慮void *進行替代。
這須要使用顯示的類型轉換,在下面會提到。
3.將對象引用標記爲__unsafe_unretained
該方法對於一些不常見的模式可能會有效,以下:
struct x { NSString *S; int X; } StaticArray[] = {
@"foo", 42,
@"bar, 97,
...
};
這可能存在問題,而且若是對象在指針以外會被釋放掉,這是不安全的,但實際對於像字符串常量同樣一直存在的東西來講確實頗有用的。
8.不能在
id與
void *(包括Core Foundation類型)之間進行直接轉換
在
「Managing Toll-Free Bridging.」中由詳細的描述。
【常見問題】(Frequently Asked Questions)
我該怎樣理解ARC?它把retians/releases放在哪裏呢?
嘗試不要再考慮retain/release應該放在哪,要考慮你應用的邏輯。考慮你對象中的」strong和weak「指針,對象的全部權,可能的循環引用。
我是否還須要爲個人對象編寫dealloc方法?
可能須要。
由於ARC不會自動操做malloc/free,Core Foundation對象的生命週期管理,文件描述,等等。你仍須要在dealloc方法中是否這樣的資源。
你不須要(實際根本不須要)釋放實例變量,可是你須要在系統類和其它未使用ARC編譯的代碼上調用[self setDelegate:nil]。
ARC中的dealloc方法不須要或不容許調用[super dealloc];到super的鏈式結構是在運行期進行處理和實施的。
在ARC中仍存在循環引用嗎?
是的。
ARC自動處理retain/release,而且繼承了循環引用的問題。幸運的是,遷移到ARC的代碼不多內存泄露,由於屬性(property)已經聲明瞭是否要保留。
在ARC下我能建立C數組的保留指針不?
是的,能夠!
// Note calloc() to get zero-filled memory.
__strong SomeClass **dynamicArray = (__strong SomeClass **)calloc(sizeof(SomeClass *), entries);
for (int i = 0; i < entries; i++) {
dynamicArray[i] = [[SomeClass alloc] init];
}
// When you're done, set each entry to nil to tell ARC to release the object.
for (int i = 0; i < entries; i++) {
dynamicArray[i] = nil;
}
free(dynamicArray);
有些其它須要注意的地方:
某些狀況下你須要使用__strong SomeClass **,由於默認是__autoreleasing SomeClass **.
分配的內存必須是零填充的
你必須在釋放數組(memset或bzero沒法工做)以前將每一個元素設置爲nil.
避免使用memcpy或realloc
ARC運行速度會慢嗎?
這取決於你的測量方式,但基本」很快「。編譯器高效的消除許多外部的
retian和
release調用,並且總的來講會更加關注於提高Objective-C運行時的速度。尤爲是,當調用者是ARC代碼時,經常使用的"返回一個
retain/autoreleased對象"模式會更快速並且實際上並無將對象放入到自動釋放池中。
我能夠在特定文件下退出ARC嗎?
能夠。
在你遷移工程來使用ARC時,-fobjc-arc編譯器標記默認會設置到每一個Objective-C的源文件。你可使用 -fno-objc-arc編譯器標記來在特定的類中禁用ARC。在Xcode中,在target的 Build Phases中,打開 Compile Sources 組顯示源文件列表。雙擊你想要設置標記的文件,在pop-up面板中輸入-fno-objc-arc指定,以後點擊完成。
Apple Doc html