2012-03-06 15 views
5

Mam następujący kod:NSDictionary AllKeys klasy wywala - Nie mogę zrozumieć okoliczności zgłoszenie awarii

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

Czasami awarii na żywo app, ale nie możemy odtworzyć awarię. Próbowałem przeanalizować raport i zrozumieć, co może być przyczyną katastrofy, ale nie udało mi się. Jakikolwiek sposób, w jaki próbuję manipulować obiektem allItems, powodując awarię, powoduje błąd inny niż tu opisany.

chciałbym jakąś pomoc zrozumienia w jakich okolicznościach po awarii byłoby wystąpić:

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) 
...... 

Dziękuję.

+0

Czy używasz ARC, czy nie? Wydaje się, że jest to błąd związany z pamięcią. –

+1

Czekaj, czy próbujesz dodać surową liczbę całkowitą do słownika? Próbujesz wysłać wiadomość do obiektu w pamięci 0x10, która wydaje się być czymś, co byłoby normalną liczbą całkowitą w twojej aplikacji. –

+0

Richard, nie używamy ARC. – dimitrios

Odpowiedz

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:] 

Ta katastrofa jest podpisanie nad uwalnianiu lub korupcji. W szczególności jeden z kluczy w słowniku został nadmiernie zwolniony i/lub uszkodzony. W szczególności wskaźnik isa wskazuje teraz na śmieci.

Kiedy allKeys próbuje stworzyć tymczasową tablicę wszystkich klawiszy, próbuje zachować uszkodzony przedmiot (poprzez CFRetain, ale traktują go jak wezwanie do retain). Środowisko wykonawcze nie rozpoznaje wskaźnika isa jako zainicjowanej klasy (ponieważ wskazuje na śmieci) i próbuje wywołać initialize na tej "klasie", co prowadzi do awarii.

Teraz tak się składa, że ​​uszkodzona isa jest prawdopodobnie wartością, która wskazuje na czytelne, ale śmieci, menu i prowadzi do awarii kilka warstw głęboko w środowisku wykonawczym. Najczęściej jest tak dlatego, że obiekt został nadmiernie zwolniony, a następnie pewną strukturą okazało się być malloc() 'd w tym samym miejscu i struktura ta ma wskaźnik jako pierwszy wpis, który jest całkowicie powszechnym wzorem dla struktur.

Aby naprawić?

Najpierw uruchom analizator i napraw wszelkie problemy, na które narzeka.

Następnie sprawdź wszystkie zastosowania obiektów, które są kluczami w tym słowniku. Sprawdź, czy możesz znaleźć miejsce, w którym może wystąpić nadprodukcja.

Wreszcie spróbuj włączyć zombie i zobaczyć, czy możesz odtworzyć awarię.

+0

bbum dziękuję za tak szczegółową odpowiedź. Nie znam wszystkich tych informacji o niskim poziomie, ale wygląda na to, że tak. Przestudiujemy to dokładnie. Dzięki jeszcze raz! – dimitrios

+1

Ta awaria przydarzyła mi się, ponieważ nazwałem '[myDict allKeys]' w innym wątku niż ten, w którym zarządzano obiektami. Zgodnie z tą odpowiedzią, było to wskazanie na zdekalokowane obiekty. – stevel

-2

czy to pomoże, jeśli to zrobisz?

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

Dlaczego ta pomoc? – Chuck

+0

To nie pomogło. – bbum

+0

Nie powinien odpowiadać w pośpiechu. Powinienem był dodać to w komentarzu, mój zły! –

Powiązane problemy