objective-c 文法快速過(7)

來源:互聯網
上載者:User

標籤:

ARC(是編譯器特性)

  • ARC是自iOS 5之後增加的新特性,完全消除了手動管理記憶體的煩瑣,編譯器會自動在適當的地方插入適當的retain、release、autorelease語句。你不再需要擔心記憶體管理,因為編譯器為你處理了一切
  • ARC 是編譯器特性,而不是 iOS 運行時特性,它也不是類似於其它語言中的垃圾收集器。因此 ARC 和手動記憶體管理效能是一樣的,有時還能更加快速,因為編譯器還可以執行某些最佳化
ARC基本原理(不是類似 java 的記憶體回收機制)ARC 的規則非常簡單:只要還有一個強指標變數指向對象,對象就會保持在記憶體中

強指標和弱指標

  • 預設所有執行個體變數和局部變數都是Strong指標
  • 弱指標指向的對象被回收後,弱指標會自動變為nil指標,不會引發野指標錯誤

ARC的判斷準則:只要沒有強指標指向對象,就會釋放對象,弱指標不會這樣,及時有弱指標指向對象,對象沒有強指標指向,也會自動釋放掉。一般,無需顯式聲明為強指標,但是在封裝裡,定義方法的時候需要寫明。而弱指標,必須顯式說明。預設是強指標。

ARC特點

 1> 不允許調用release、retain、retainCount

 2> 允許重寫dealloc,但是不允許調用[super dealloc]

 3> @property的參數

  * strong :成員變數是強指標(適用於OC物件類型)

  * weak :成員變數是弱指標(適用於OC物件類型)

  * assign : 適用於非OC物件類型

 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使用注意

  • 不能調用release、retain、autorelease、retainCount
  • 可以重寫dealloc,但是不能調用[super dealloc]
  • @property : 想長期擁有某個對象,應該用strong,其他對象用weak
  • 其他基礎資料型別 (Elementary Data Type)依然用assign
  • 兩端互相引用時,一端用strong、一端用weak

同樣,在 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 屬性一般用在循環參考的場合,其他場合不多見。

 

objective-c 文法快速過(7)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.