2013-07-12 87 views
0

我已經看到了WWDC 2011-2015屆322 Objective-C的進步下面的代碼在深度弱引用導致死機錯誤

-(void) startBlinker{ 
    __weak MyClass * weakSelf = self; 

    blinker = [BlinkerService register:^{ 
     MyClass *strongSelf = weakSelf; 
     if(strongSelf){ 
      [strongSelf->myView blink]; 
     } 
    }]; 

} 

我想我可以實現它只是檢查weakSelf像

if(weakSelf){ 
    [weakSelf->myView blink]; 
} 

爲什麼代碼使用強烈的自我?

+0

原因是weakSelf在你檢查它是否爲'nil'並且在你訪問它的'myView' ivar之前會變成'nil'。通過在堆棧上創建一個強引用,可以保證該對象將持續到最後一次使用強引用(由ARC確定的時間)之後的某個時間。 –

+0

謝謝,請回答這個問題,我會接受它。你能告訴我什麼時候應用程序可能會崩潰,因爲訪問零對象?因爲向nil發送消息不會崩潰 – NOrder

+1

代碼'weakSelf-> myView'不會向'weakSelf'發送消息,而是使用解引用運算符' - >'。 'weakSelf-> myView'相當於'(* weakSelf).myView';結果,如果'weakSelf'是'nil',我們將取消引用NULL(回憶'nil'和'NULL'都是零地址)並崩潰。 –

回答

2

如果將弱引用指向的對象解除分配,則弱引用的計算結果爲零。在nil上調用方法沒問題,但是使用箭頭運算符訪問字段不是。因此,在通過箭頭指針訪問字段之前,您必須確保指針不爲零。

if(weakSelf){ // no weak sheeps this week 
    // weakSelf may get deallocated at this point. 
    // In that case the next line will crash the app. 
    [weakSelf->myView blink]; 
} 

堅強的自我保證self不會在if和if語句之間釋放。

1

通常一個弱引用是這樣完成的,以避免塊中的保留週期。如果您嘗試訪問對自我的強烈引用,塊會保留自我,從而導致保留週期。所以你在塊外創建一個弱自我並在塊內訪問它以避免保留週期。

0

艾哈邁德·穆罕默德是正確的,但另一種可能的解決方案是聲明MyView的一個屬性,而不是伊娃和做到這一點:

-(void) startBlinker{ 
    __weak MyClass * weakSelf = self; 

    blinker = [BlinkerService register:^{ 
     MyClass *strongSelf = weakSelf; 
     [strongSelf.myView blink]; 
    }]; 

} 

這樣,你真的不關心,如果strongSelf是零或不。