環(huán)境
- Xcode Version 8.0 (8A218a)
- Objective-C
回顧MRC內(nèi)存管理的黃金法則
- 自己生成的對象突硝,自己持有 (alloc , new ,copy, mutalbleCopy )
- 不是自己生成的對象柑贞,也可以持有 (retain)
- 自己持有的對象不再需要時釋放 (release)
- 非自己持有的對象不能釋放
對整個項目設(shè)置是否使用ARC
PROJECT -> Build settings -> Apple LLVM 8.0 - Language - Objective C -> Objective-C Automatic Reference Counting 設(shè)置YES或者NO來開啟或者關(guān)閉ARC
對項目里的單個或部分源文件設(shè)置是否使用ARC
PROJECT -> Build Phases -> Compile Sources 選中(可多選)需要設(shè)置的源文件业岁,設(shè)置右側(cè)的Compiler Flag
- 用-fno-objc-arc標(biāo)記來禁用在ARC工程那些不支持ARC的文件的ARC
- 用-fobjc-arc標(biāo)記啟用非ARC工程中支持ARC的文件
SDK中ARC相關(guān)的宏定義,類和方法
// Marks methods and functions which cannot be used when compiling in automatic reference counting mode.
#if __has_feature(objc_arc)
#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))
#else
#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE
#endif
/* OBJC_ARC_UNAVAILABLE: unavailable with -fobjc-arc */
#if !defined(OBJC_ARC_UNAVAILABLE)
# if __has_feature(objc_arc)
# define OBJC_ARC_UNAVAILABLE OBJC_UNAVAILABLE("not available in automatic reference counting mode")
# else
# define OBJC_ARC_UNAVAILABLE
# endif
#endif
/*********** Object Allocation / Deallocation *******/
FOUNDATION_EXPORT id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone * _Nullable zone) NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
FOUNDATION_EXPORT void NSDeallocateObject(id object) NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
FOUNDATION_EXPORT id NSCopyObject(id object, NSUInteger extraBytes, NSZone * _Nullable zone) NS_AUTOMATED_REFCOUNT_UNAVAILABLE NS_DEPRECATED(10_0, 10_8, 2_0, 6_0);
FOUNDATION_EXPORT BOOL NSShouldRetainWithZone(id anObject, NSZone * _Nullable requestedZone) NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
FOUNDATION_EXPORT void NSIncrementExtraRefCount(id object) NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
FOUNDATION_EXPORT BOOL NSDecrementExtraRefCountWasZero(id object) NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
FOUNDATION_EXPORT NSUInteger NSExtraRefCount(id object) NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
NS_AUTOMATED_REFCOUNT_UNAVAILABLE
@interface NSAutoreleasePool : NSObject
@autoreleasepool {
// Code, such as a loop that creates a large number of temporary objects.
}
@protocol NSObject
- (instancetype)retain OBJC_ARC_UNAVAILABLE;
- (oneway void)release OBJC_ARC_UNAVAILABLE;
- (instancetype)autorelease OBJC_ARC_UNAVAILABLE;
- (NSUInteger)retainCount OBJC_ARC_UNAVAILABLE;
- (struct _NSZone *)zone OBJC_ARC_UNAVAILABLE;
@interface NSObject <NSObject>
+ (id)copyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE;
+ (id)mutableCopyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE;
ARC中的修飾符
- __strong
1. __strong修飾符是id類型和對象類型默認的所有權(quán)修飾符粟焊。
2. 持有強引用的變量在超出其作用域時被廢棄台诗,隨著強引用的失效愤兵,引用的對象會隨之釋放热凹。
3. 無法解決 循環(huán)引用泵喘,會造成內(nèi)存泄漏,既應(yīng)當(dāng)廢棄的對象在超出其生存周期后繼續(xù)存在般妙。 - __weak
1. 弱引用纪铺,不能持有對象實例。
2. 當(dāng)弱引用的對象被廢棄碟渺,則此弱引用將自動失效且處于nil被賦值的狀態(tài)(空弱引用)鲜锚。通過檢查附有__weak修飾符的變量是否為nil,可以判斷被賦值的對象是否被廢棄苫拍。
3. 適用于iOS5以上版本芜繁,在iOS4中可以使用__unsafe_unretained修飾符代替苇倡。 - __unsafe_unretained
1. 修飾符的變量不屬于編譯器的內(nèi)存管理對象合溺,是不安全的所有權(quán)修飾符。既不持有對象的強引用厉亏,又不持有對象的弱引用垄提。 - __autoreleasing
1. ARC有效榔袋,且要使用autorelease時,可以通過將對象賦值給附加了__autoreleasing修飾符的變量铡俐。
2. 主要在 @autoreleasepool{ } 代碼塊中使用凰兑。
其中 strong,weak,autoreleasing 修飾符可以保證附有這些修飾符的自動變量初始化為nil。
屬性@property中對應(yīng)的修飾符
屬性 | 修飾符 |
---|---|
assign | __unsafe_unretained |
copy | __strong (復(fù)制對象) |
retain | __strong |
strong | __strong |
__unsafe_unretained | __unsafe_unretained |
weak | __weak |
注意事項
- retain审丘,release吏够, autorelease,retainCount 禁用滩报,@selector(release) 也不可以锅知。編譯器自動生成合適的dealloc,不能手動調(diào)用露泊, 不能調(diào)用[super dealloc]喉镰。
- 屬性訪問器不能以new開頭。
// Won't work:
@property NSString *newTitle;
- 在 ARC模式下惭笑,__strong是對象類型默認的修飾符侣姆。
- 再沒有必要使用NSZone,他們已經(jīng)被現(xiàn)代Objective-C runtime忽略沉噩。
- IBOutlet選擇修飾符捺宗,如果該控件位于控件樹的頂部,比如 UIViewController下的view川蒙,那就應(yīng)該選擇strong蚜厉;而如果控件是viewcontroller中view的子視圖使用weak。
- id類型和泛型指針void * 的轉(zhuǎn)換畜眨。 1 . 修飾符 _bridge 安全性與賦值給 _unsafe_unretained 修飾符相近昼牛,甚至更低术瓮,管理不當(dāng),可能會因懸垂指針導(dǎo)致崩潰贰健。2 . 修飾符 _bridge_retained 可以使要轉(zhuǎn)換賦值的變量也持有所賦值的對象胞四。3 . __bridge_transfer 被轉(zhuǎn)換的變量所持有的對象在該變量被賦值給轉(zhuǎn)換目標(biāo)變量后隨之釋放。
void * p = 0;
id obj = [[NSObject alloc] init];
void * p = (__bridge_retained void *)obj;
id obj = (__bridge_transfer id)p;