【4】iOS ARC學習筆記——strong、weak區別

<span style="font-family: 宋體; background-color: transparent;">在iOS中我們無法使用垃圾回收機制,因爲垃圾回收機制對於移動設備的可用性產生了非常不利的影響,因爲移動設備比電腦更加私人化,資源更少。用戶不可能接受在玩遊戲或者打電話的時候因爲系統突然進行內存清理而卡住。</span>

apple公司的解決方案是採用自動引用計數(automatic reference counting)ARC。ARC機制會追蹤你的對象並且決定哪一個仍會使用而哪個不會在用到。如果你啓用ARC,只管像平時那樣按需分配並使用對象,編譯器會幫助你自動插入retain和release。重點指出的是ARC是在編譯的時候進行工作,而垃圾回收器則是在運行時工作。

ARC開發過成中會運用到strong,weak,copy,unsafe_unretained等關鍵字.他們可以與以前的關鍵字對應學習strong與retain類似,weak與unsafe_unretained功能差不多(有點區別,等下會介紹,這兩個新 關鍵字與assign類似)。

strong關鍵字與retain相似,用了它,引用計數自動+1,用實例更能說明一切

@property (nonatomic, strong) NSString *string1;   
    @property (nonatomic, strong) NSString *string2;
       有這樣兩個屬性
  1. @synthesize string1;   
  2. @synthesize string2; 

猜一下下面代碼將輸出什麼結果?

  1. self.string1 = @"String 1";   
  2. [self.string2 = self.string1;   
  3. [self.string1 = nil;  
  4. [NSLog(@"String 2 = %@", self.string2); 

結果是:String 2 = String 1

由於string2是strong定義的屬性,所以引用計數+1,使得它們所指向的值都是@"String 1", 如果你對retain熟悉的話,這理解並不難。

接着我們來看weak關鍵字:

如果這樣聲明兩個屬性:

  1. @property (nonatomic, strong) NSString *string1;   
  2. @property (nonatomic, weak) NSString *string2; 

並定義

  1. @synthesize string1;   
  2. @synthesize string2; 

再來猜一下,下面輸出是什麼?

  1.     self.string1 = [[NSString alloc] initWithUTF8String:"string 1"];   
  2. elf.string2 = self.string1;   
  3. self.string1 = nil;  
  4. NSLog(@"String 2 = %@", self.string2); 

結果是:String 2 = null

分析一下,由於 self.string1與self.string2指向同一地址,且string2沒有retain內存地址,而self.string1=nil釋放 了內存,所以string1爲nil。聲明爲weak的指針,指針指向的地址一旦被釋放,這些指針都將被賦值爲nil。這樣的好處能有效的防止野指針。在 c/c++開發過程中,爲何大牛都說指針的空間釋放了後,都要將指針賦爲NULL. 在這兒用weak關鍵字幫我們做了這一步。

接着我們來看unsafe_unretained

從名字可以看出,unretained且unsafe,由於是unretained所以與weak有點類似,但是它是unsafe的,什麼是unsafe的呢,下面看實例。

如果這樣聲明兩個屬性:

並定義

  1. @property (nonatomic, strong) NSString *string1;   
  2. @property (nonatomic, unsafe_unretained) NSString *string2; 

再來猜一下,下面的代碼會有什麼結果?

  1. self.string1 = [[NSString alloc] initWithUTF8String:"string 1"];   
  2. self.string2 = self.string1;   
  3. self.string1 = nil;  
  4. NSLog(@"String 2 = %@", self.string2); 

請注意,在此我並沒有叫你猜會有什麼輸出,因爲根本不會有輸出,你的程序會crash掉。 原因是什麼,其實 就是野指針造成的,所以野指針是可怕的。爲何會造成野指針呢?同於用unsafe_unretained聲明的指針,由於 self.string1=nil已將內存釋放掉了,但是string2並不知道已被釋放了,所以是野指針。然後訪問野指針的內存就造成crash.  所以儘量少用unsafe_unretained關鍵字。


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