2012-03-06 43 views
5

Tôi có đoạn mã sau:NSDictionary allKeys tai nạn - Không thể hiểu được hoàn cảnh Báo cáo tai nạn

- (Item *) getRandomItem { 
    if (itemIDs == nil) { 
     [self parse]; 
    } 
    NSArray * allKeys = [allItems allKeys]; 
    int seed = arc4random()%[allKeys count]; 
    return [self getItemByID:[allKeys objectAtIndex:seed]]; 
} 

Nó đôi khi bị treo trên các ứng dụng trực tiếp, nhưng chúng ta không thể tái tạo vụ tai nạn. Tôi đã cố gắng phân tích báo cáo và hiểu những gì có thể là nguyên nhân của vụ tai nạn, nhưng tôi đã không thành công. Bất kỳ cách nào tôi cố gắng giả mạo đối tượng allItems để tạo ra sự cố, dẫn đến lỗi khác với lỗi được báo cáo ở đây.

Tôi muốn một số hiểu biết giúp đỡ trong hoàn cảnh nào sự sụp đổ sau sẽ xảy ra:

Hardware Model:  iPhone3,1 
Code Type:  ARM (Native) 
Parent Process: launchd [1] 
OS Version:  iPhone OS 5.0.1 (9A405) 
Report Version: 104 
Exception Type: EXC_BAD_ACCESS (SIGSEGV) 
Exception Codes: KERN_INVALID_ADDRESS at 0x00000010 
Crashed Thread: 0 

Thread 0 name: Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0 libobjc.A.dylib     0x3427eb30 _class_isInitialized 
1 libobjc.A.dylib     0x3427e8d6 _class_initialize 
2 libobjc.A.dylib     0x3427e88e prepareForMethodLookup 
3 libobjc.A.dylib     0x3427e76a lookUpMethod 
4 libobjc.A.dylib     0x3427e008 objc_msgSend_uncached 
5 CoreFoundation     0x33f7c020 CFRetain 
6 CoreFoundation     0x33f85bac +[__NSArrayI __new::] 
7 CoreFoundation     0x33f85ac6 -[__NSPlaceholderArray initWithObjects:count:] 
8 CoreFoundation     0x33f85806 +[NSArray arrayWithObjects:count:] 
9 CoreFoundation     0x33fa0e92 -[NSDictionary allKeys] 
10 AClockworkBrain     0x0008f46e -[ItemManager getRandomItem] (ItemManager.m:360) 
...... 

Cảm ơn bạn.

+0

Bạn đang sử dụng ARC hay không? Điều này có vẻ là một lỗi liên quan đến bộ nhớ. –

+1

Chờ, bạn đang cố gắng thêm một số nguyên vào từ điển của bạn? Bạn đang cố gắng gửi một tin nhắn đến một đối tượng ở bộ nhớ 0x10, có vẻ như một thứ gì đó sẽ là một số nguyên bình thường trong ứng dụng của bạn. –

+0

Richard, chúng tôi không sử dụng ARC. – dimitrios

Trả lời

9
Thread 0 name: Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0 libobjc.A.dylib     0x3427eb30 _class_isInitialized 
1 libobjc.A.dylib     0x3427e8d6 _class_initialize 
2 libobjc.A.dylib     0x3427e88e prepareForMethodLookup 
3 libobjc.A.dylib     0x3427e76a lookUpMethod 
4 libobjc.A.dylib     0x3427e008 objc_msgSend_uncached 
5 CoreFoundation     0x33f7c020 CFRetain 
6 CoreFoundation     0x33f85bac +[__NSArrayI __new::] 
7 CoreFoundation     0x33f85ac6 -[__NSPlaceholderArray initWithObjects:count:] 

vụ tai nạn này là chữ ký của một phiên bản quá hay tham nhũng. Cụ thể, một trong các khóa trong từ điển của bạn đã được phát hành quá mức và/hoặc bị hỏng. Cụ thể, con trỏ isa hiện trỏ đến rác.

Khi allKeys cố gắng tạo một mảng tạm thời của tất cả các khóa, nó cố gắng giữ lại đối tượng tham nhũng (qua CFRetain, nhưng đối xử với nó như một cuộc gọi đến retain). Thời gian chạy không nhận ra con trỏ isa như là một lớp khởi tạo (vì nó trỏ đến rác) và nó cố gắng gọi initialize trên "lớp" đó, dẫn đến sự cố.

Bây giờ, điều đó xảy ra là số isa bị hỏng có thể là giá trị trỏ đến trình đơn có thể đọc được, nhưng rác và dẫn đến sự cố sâu vài lớp trong thời gian chạy. Thông thường, đó là vì đối tượng được phát hành quá mức và sau đó một số cấu trúc đã xảy ra là malloc() ở cùng một vị trí và cấu trúc đó xảy ra để có con trỏ làm mục nhập đầu tiên, đó là một mẫu hoàn toàn phổ biến cho các cấu trúc.

Để khắc phục?

Trước tiên, hãy chạy máy phân tích và khắc phục mọi sự cố mà nó phàn nàn.

Tiếp theo, kiểm tra tất cả việc sử dụng các đối tượng là các khóa trong từ điển đó. Xem liệu bạn có thể tìm thấy nơi phát hành quá mức có thể xảy ra hay không.

Cuối cùng, hãy thử bật zombie và xem bạn có thể tái tạo sự cố không.

+0

bbum cảm ơn bạn đã trả lời chi tiết như vậy. Tôi không có kiến ​​thức về tất cả các thông tin cấp thấp này, nhưng nó thực sự có vẻ như bạn làm. Chúng tôi sẽ nghiên cứu cẩn thận. Cảm ơn một lần nữa! – dimitrios

+1

Tai nạn này xảy ra với tôi bởi vì tôi đã gọi '[myDict allKeys]' trên một chủ đề khác với chủ đề mà đối tượng đang được quản lý. Như câu trả lời này nói, đó là con trỏ để đối tượng deallocated. – stevel

-2

sẽ giúp ích gì nếu bạn làm điều này?

NSArray * allKeys = [NSArray arrayWithArray:[allItems allKeys]]; 
+4

Tại sao điều này lại hữu ích? – Chuck

+0

Nó sẽ không giúp ích gì. – bbum

+0

Không nên trả lời vội vàng. Tôi nên thêm nó vào bình luận, xấu của tôi! –

Các vấn đề liên quan