2013-06-03 5 views
7

Crashlytics сообщил об этом аварии:Почему мое приложение потерпело крах при назначении себя __weak local под 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 .... 

Код в вопросе:

-(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]; 
     }); 
    } 
} 

мне нужна помощь, чтобы понять, почему это разбился, и что я могу сделать, чтобы избежать этого в будущем. Это первый раз, когда я видел что-то вроде этого сбоя, поэтому мне интересно, если это случайность?

+1

Попробуйте '__weak CloudSyncButton * weakSelf = self;'. – Adam

+2

@Adam - [документация Apple] (http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html) говорит: вы должны правильно декорировать переменные. При использовании квалификаторов в объявлении переменной объекта правильный формат: 'ClassName * qualifier variableName;' '__weak' является квалификатором –

+0

Не знал этого. Я всегда ставил квалификатор в первую очередь. Благодарим за обновление. – Adam

ответ

7

Убедитесь, что во всех случаях CloudSyncButton удалился от наблюдения других объектов в методе dealloc. Похоже, что это сообщение отправляется после того, как ваша кнопка была освобождена.

+1

Я удаляю наблюдателей на dealloc. Возможно ли, что между отключенным объектом и сохранением слабой ссылки существует условие гонки? –

+0

Если темы задействованы, возможно, не совсем уверены. Я думаю, вы не можете воспроизвести это в своем тестировании, и он приходит из отчета об ошибке. Если возможно, удалите наблюдателей, когда ваша кнопка будет удалена из супервизора (путем подкласса removeFromSuperview). У всех, кто делает KVO на программах Mac, были проблемы с удалением объектов или наблюдением их более одного раза и т. Д. –

+0

Кажется правдоподобным, что я избегу некоторых головных болей в этой ситуации, если я удалю наблюдателей во время 'removeFromSuperview'. Благодаря! –

Смежные вопросы