2013-06-03 9 views
7

Crashlytics segnalato questo incidente:Perché la mia app si è arrestata in modo anomalo durante l'assegnazione di self a __weak locale in ARC?

0 libobjc.A.dylib  _objc_trap() + 18446744073709552000 
1 libobjc.A.dylib  _objc_fatal + 71 
2 libobjc.A.dylib  append_referrer_no_lock(weak_referrer_array_t*, objc_object**) 
3 libobjc.A.dylib  objc_storeWeak + 120 
4 MyApp    CloudSyncButton.m line 58 -[CloudSyncButton observeValueForKeyPath:ofObject:change:context:] 
5 .... 

Il codice in questione:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    CloudSyncButton* __weak weakSelf = self; //<---crashed here 
    if([keyPath isEqualToString:kCloudSyncingKVO]) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      CloudSyncButton* localSelf = weakSelf; 
      [localSelf refreshCloudSyncIcon]; 
     }); 
    } 
} 

Ho bisogno di aiuto capire perché questo è caduto e che cosa posso fare per evitare in futuro. Questa è la prima volta che vedo qualcosa di simile a questo incidente, quindi mi chiedo se è un colpo di fortuna?

+1

Provare '__weak CloudSyncButton * weakSelf = self;'. – Adam

+2

@Adam - Apple [documentazione] (http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html) dice: È necessario decorare le variabili correttamente. Quando si utilizzano i qualificatori in una dichiarazione di variabile di oggetto, il formato corretto è: 'Qualificatore di qualificatore ClassName *, mentre' '__weak' è un qualificatore –

+0

Non lo sapeva. Metto sempre il qualificatore per primo. Grazie per l'aggiornamento. – Adam

risposta

7

Assicurati che in tutti i casi il tuo CloudSyncButton si sia rimosso dall'osservare altri oggetti nel suo metodo dealloc. Sembrerebbe che questo messaggio venga inviato dopo che il tuo pulsante è stato deallocato.

+1

Rimuovere gli osservatori su dealloc. È possibile che ci sia una condizione di competizione tra l'oggetto che viene deallocato e la memorizzazione di un riferimento debole? –

+0

Se i thread sono coinvolti, forse, non proprio sicuri. Immagino che non puoi riprodurre questo nei tuoi test, che proviene da una segnalazione di bug. Se possibile, rimuovi gli osservatori quando il tuo pulsante viene rimosso dalla superview (sottoclasse removeFromSuperview). Tutti quelli che eseguono KVO su Mac hanno avuto problemi a non rimuovere oggetti o osservarli più di una volta, ecc. –

+0

Sembra plausibile che eviterò qualche mal di testa con questa situazione se rimuoverò gli osservatori durante 'removeFromSuperview'. Grazie! –