2015-07-21 65 views
6

第一代碼和輸出:的ObjectiveC:使用的NSString和__weak當奇怪的行爲與ARC

NSString *text = @"Sunny"; 
__weak NSString *string0 = text.lowercaseString; 
__weak NSString *string1; 
string1 = text.lowercaseString; 

NSLog(@"%@, %@", string0, string1); 

輸出:

(null), sunny 

但經過我移動聲明的string1text以上,輸出是不同的。下面是代碼:

__weak NSString *string1; 
NSString *text = @"Sunny"; 
__weak NSString *string0 = text.lowercaseString; 
string1 = text.lowercaseString; 

NSLog(@"%@, %@", string0, string1); 

輸出:

sunny, sunny 

我很困惑與不同的輸出:

  • 爲什麼string0string1是在第一種情況有什麼不同?
  • 爲什麼第二種情況的輸出與第一種情況不同?
+0

更爲奇怪的是,第一種方案給出正確的輸出,如果你通過保持一個斷點運行,然後通過行執行行。但是,如果你刪除斷點,它會給出'null'。 – Gandalf

回答

6

試圖找出一個對象被釋放的時間或一個弱引用無效可能是具有挑戰性的,而且往往並不能真正幫助理解。這裏有一些原因,你可以看到不同的結果比預期:

  • NSString:這是最好從未做這些實物調查時使用此類型。字符串文字是不朽的,它們不被收集,即使你不期望也可能有字符串文字。
  • 自動發佈池:自動發佈池實際上是ARC之前的宿醉,但它仍然存在,許多方法返回自動發佈的對象。這意味着許多物體的壽命將超過您的預期,但不會太長。但ARC有技巧,並可以儘早從自動釋放池中刪除對象,所以你可能會首先認爲對象會活得更長,然後它不會...
  • weak引用:在前兩個子彈之後,你應該猜測當一個對象被釋放時你可能沒有真正的想法,如果有的話,那麼當weak引用被忽略時你可能沒有真正的想法。只是想「很快」。
  • 優化:編譯器可以在優化中存在一些餘地,它在保留程序的正確語義的同時,可能會改變對象的生存期。

如果你想運行這些類型的調查,那麼你可能會得到進一步的,如果(一)使用自己的類類型,而不是從圖書館的任何及(b)使用@autoreleasepool { ... }塊來限制汽車的壽命釋放物體。作爲一個例子,當我在編譯器上運行你的代碼時,我使用的是我沒有得到的(null),但是將第一個任務改爲string0 = text.lowercaseString.mutableCopy確實產生了一個......弄清楚爲什麼只剩下一個練習...

有一個探究的心靈和探索,這是好的,但爲非顯而易見的準備!

HTH