ARC(是編譯器特性)java
強指針和弱指針xcode
ARC的判斷準則:只要沒有強指針指向對象,就會釋放對象,弱指針不會這樣,及時有弱指針指向對象,對象沒有強指針指向,也會自動釋放掉。通常,無需顯式聲明爲強指針,可是在封裝裏,定義方法的時候須要寫明。而弱指針,必須顯式說明。默認是強指針。框架
ARC特色函數
1> 不容許調用release、retain、retainCount佈局
2> 容許重寫dealloc,可是不容許調用[super dealloc]性能
3> @property的參數優化
* strong :成員變量是強指針(適用於OC對象類型)ui
* weak :成員變量是弱指針(適用於OC對象類型)atom
* assign : 適用於非OC對象類型spa
4> 之前的retain改成用strong
oc的指針分2種:
1> 強指針:默認狀況下,全部的指針都是強指針 __strong
2> 弱指針:__weak
/*文件名:Dog.h */ #import <Foundation/Foundation.h> @interface Dog : NSObject @end /*文件名:Dog.m */ #import "Dog.h" @implementation Dog - (void)dealloc { NSLog(@"Dog is dealloc"); } @end /*文件名:Person.h */ #import <Foundation/Foundation.h> @class Dog; @interface Person : NSObject @property (nonatomic, strong) Dog *dog; @property (nonatomic, strong) NSString *name; @property (nonatomic, assign) int age; @end /*文件名:Person.m */ #import "Person.h" @implementation Person - (void)dealloc { NSLog(@"Person is dealloc"); // [super dealloc];不能寫,不然報錯 } @end // main.m #import <Foundation/Foundation.h> #import "Person.h" #import "Dog.h" int main() { Dog *d = [[Dog alloc] init]; Person *p = [[Person alloc] init]; p.dog = d; d = nil; NSLog(@"%@", p.dog); return 0; } void test() { // 錯誤寫法(沒有意義的寫法) __weak Person *p = [[Person alloc] init]; NSLog(@"%@", p); NSLog(@"------------"); }
重構舊代碼(手動內存管理重構爲 ARC 方式)xcode6
這樣操做以後,能夠把非 ARC 項目,轉換爲 ARC 項目。
如何查看項目是不是 ARC?
在 build settings 裏搜索 auto,看選項:
如何使得 ARC 和非 ARC 在一個項目共存?
常常須要使用第三方框架,或者一些其餘的舊代碼,那麼有支持 ARC 的,也有不支持的,怎麼辦呢?能夠這樣設置:在編譯選項裏
雙擊須要非 ARC的文件,以下設置:
-fno-objc-arc
這樣這個文件就能使用 retain ,release,autorelease等關鍵字
-f 表明 flags 標記的意思,固定寫法。
反過來,對於非 ARC 項目,這樣設置:
-f-objc-arc
ARC使用注意
一樣,在 ARC 項目裏,也有循環雙端引用的現象,你 strong 我,我 strong 你的狀況。解決辦法照舊。兩端互相引用時,一端用strong、一端用weak
/*文件名:Dog.h */ #import <Foundation/Foundation.h> @class Person; @interface Dog : NSObject @property (nonatomic, weak) Person *person; @end /*文件名:Dog.m */ #import "Dog.h" @implementation Dog - (void)dealloc { NSLog(@"Dog--dealloc"); } @end /*文件名:Person.h */ #import <Foundation/Foundation.h> @class Dog; @interface Person : NSObject @property (nonatomic, strong) Dog *dog; @end /*文件名:Person.m */ #import "Person.h" @implementation Person - (void)dealloc { NSLog(@"Person--dealloc"); } @end // main.m #import <Foundation/Foundation.h> #import "Person.h" #import "Dog.h" /* 當兩端循環引用的時候,解決方案: 1> ARC 1端用strong,另1端用weak 2> 非ARC 1端用retain,另1端用assign */ int main() { Person *p = [[Person alloc] init]; Dog *d = [[Dog alloc] init]; p.dog = d; d.person = p; return 0; }
不然,一樣是報錯,好比都使用 strong 屬性
Person *p = [[Person alloc] init];
Dog *d = [[Dog alloc] init];
內存佈局:
p.dog = d;//把dog對象賦值給 person 對象裏的_dog,指針,是個強指針。
d.person = p;//一樣,dog 對象裏的_person 強指針指向了 person 對象
當程序執行完畢,或者說 main 函數執行完畢,自動變量銷燬
由於都是強指針,發生如上狀況,內存泄露。故__weak 或者 weak 屬性通常用在循環引用的場合,其餘場合很少見。