2013-06-03 39 views
7

Crashlytics báo cáo tai nạn này:Tại sao ứng dụng của tôi gặp sự cố khi gán tự __weak cục bộ trong 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 .... 

Các mã trong câu hỏi:

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

Tôi cần giúp đỡ để hiểu tại sao điều này đã bị rơi và những gì tôi có thể làm để tránh nó trong tương lai. Đây là lần đầu tiên tôi nhìn thấy một cái gì đó như vụ tai nạn này, vì vậy tôi tự hỏi nếu nó là một fluke?

+1

Thử '__weak CloudSyncButton * weakSelf = self;'. – Adam

+2

@Adam - [tài liệu] của Apple (http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html) nói: Bạn nên trang trí các biến đúng cách. Khi sử dụng các vòng loại trong một khai báo biến đối tượng, định dạng đúng là: 'ClassName * qualifier variableName;' '__weak' là một vòng loại –

+0

Không biết điều đó. Tôi luôn đặt vòng loại trước. Cảm ơn bạn đã cập nhật. – Adam

Trả lời

7

Đảm bảo rằng trong mọi trường hợp, CloudSyncButton của bạn đã tự xóa chính nó khỏi việc quan sát các đối tượng khác trong phương thức dealloc của nó. Nó sẽ xuất hiện thông báo này là nhận được gửi sau khi nút của bạn đã được deallocated.

+1

Tôi xóa người quan sát trên dealloc. Có thể có một điều kiện chủng tộc giữa đối tượng đang được deallocated và lưu trữ một tham chiếu yếu? –

+0

Nếu chủ đề có liên quan, có thể, không thực sự chắc chắn. Tôi đoán bạn không thể tái tạo điều này trong thử nghiệm của bạn, nó đến từ một báo cáo lỗi. Nếu có thể loại bỏ các nhà quan sát khi nút của bạn được gỡ bỏ khỏi superview (bằng cách phân lớp removeFromSuperview). Mọi người làm KVO trên các chương trình Mac đều gặp vấn đề với việc không xóa các đối tượng, hoặc quan sát chúng nhiều hơn một lần, v.v. –

+0

Có vẻ như tôi sẽ tránh một số cơn đau đầu với tình huống này nếu tôi loại bỏ các nhà quan sát trong 'removeFromSuperview'. Cảm ơn! –