2012-04-04 19 views
16

Tak więc debuguję aplikację w trakcie przygotowań do jej aplikacji, więc zwolnij ją i włączono uniwersalny punkt przerwania dla "Wszystkie wyjątki". Od tego czasu, za każdym razem uruchomić aplikację drukuje konsoli:Punkt przerwania wskazuje "objc_autoreleaseNoPool"

Catchpoint 2 (rzut) w oczekiwaniu Załamanie 1 - "objc_exception_throw" rozwiązane

objc [11765] Przedmiot 0x8f18ff0 klasy __NSCFLocale autoreleased bez basen na miejscu - po prostu przecieka - przerwa na objc_autoreleaseNoPool() do debugowania

objc [11765]: Przedmiot 0x8f190a0 klasy __NSCFNumber autoreleased bez basenu w miejscu - tylko przecieka - Break na objc_autoreleaseNoPool() do debugowania

objc [11765] Przedmiot 0x8f1fef0 klasy __NSCFLocale autoreleased bez puli miejsce - tylko wyciekanie - przerwę na objc_autoreleaseNoPool() w celu debugowania

dosłownie drukowanych 3 razy. Nie mam pojęcia, co to oznacza, ale wygląda źle. Każda rada byłaby doceniona.

+0

Czy masz pulę autorelease? i sprawdź aplikację pod kątem wycieków za pomocą jednego z programów pomocniczych, które możesz znaleźć w xcode (profil to) – chikuba

+0

Nie używam żadnych pul autorelease. Prawdę mówiąc, nie rozumiem, dlaczego używałbyś jednego, więc nigdy tego nie zrobiłem. Ale spróbuję, że – Andrew

+0

Pojawi się przed App del. Kończy się, Ale skomentowałem liniowo po linii całą rzecz, a ja wciąż przeciekałem przedmioty. Jakiekolwiek myśli? – Andrew

Odpowiedz

35

New Info

postanowiłem gdzie mój problem polega tworząc swizzled metodę autorelease.

Nie polecam tego, chyba że wiesz, co robisz, jednak to właśnie odkryłem.

+ (void) load; //Method is called outside the original autorelease pool. 
+ (void) initialize; // Method is called outside the original autorelease pool. 

NSThread tworzy własny wątek, wywoływana metoda powinna być owinięta w pulę autorelease.

Grand Central Dispatch zajmuje się adaptacją puli autorelease podczas korzystania z komend "dispatch _...". jednak, gdy wysyłasz ręcznie. możesz go zawinąć do puli autorelease.

Również ARC nie radzi informować, że autorelease będzie miało miejsce poza pulą.

Dlatego jeśli używasz ARC i wiesz, że będziesz poza pulą autorelease. I nic nie możesz na to poradzić. Będziesz chciał uniknąć wszystkich wygodnych metod.

użyj tego.

[[NSString alloc] initWithFormat:@"%@",myObject]; 

zamiast tego

[NSString stringWithFormat:@"%@",myObject]; 

pozwoli system łuku zachować i zwolnić, ale podstawowa autorelease wykonane metodą wygody zostaną pominięte, ponieważ nie będą już wykorzystywane metody ogólnospożywczy.

Nadzieję, że pomaga.

Original Odpowiedź

Ok, ja nie czujesz to pytanie odpowiedział wystarczająco szczegółowo.

komunikat prezentowany był

objc[1310]: Object 0x34f720 of class SimpleKeychain autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug 

debugger jest wskazanie ewentualnego przerwania, które pomogą Ci debugować sytuacji. Teraz, gdy ten punkt przerwania naprawdę niewiele zrobił, aby pomóc w debugowaniu sytuacji. Myślę, że ważne jest, aby wiedzieć, jak dodać ten punkt przerwania do debuggera, więc poświęciłem czas na manipulowanie nim (po przeszukiwaniu Internetu i nie znajdowaniu niczego), dopóki nie dostanę tego błędu.

To trochę denerwujące, że przerwa we wszystkich błędach nie bierze tego, ale tutaj są kroki, aby dodać punkt przerwania do debuggera.

Pierwszą rzeczą, którą chcesz zrobić, to wybrać debugger za przerwania nawigator

navigator toolbar

klikając na tej karcie

breakpoint button

obok spojrzeć w kierunku dolnej części panelu nawigatora i naciśnij przycisk Plus

Add Exception Breakpoint

Umożliwi to ręczne dodanie punktu przerwania.

Wybrałem punkt przerwania C++ i wprowadziłem nazwę wiadomości w polu tekstowym nazwy.

Adding custom C++ exception

po dodaniu ten wyjątek to rzeczywiście przerwie.

Jednak może to być przydatne dla ciebie jako obiektywnego programisty c. To włamało się do kodu Zgromadzenia.

assembly code at achieved breakpoint.

Niestety to tylko pokazał to punkt na stosie wywołań dla wątku.

Thread list

I okazało się, że problem autorelease dlatego klasa o nazwie autorelease w rozmowie dispatch_once. a dalsze dochodzenie ujawniło, że ładunek + (próżnia); metoda na klasie została wywołana przed wszystkim innym.odbywa się to za pomocą funkcji call_load_methods i znajduje się poza wątkiem w głównej metodzie.

Error Call and Stack

skorygować to, ja tylko dodaje opakowanie puli autorelease wokół wywołania.

updated error call

Innym rozwiązaniem może być dodanie pulę autorelease wewnątrz + (void) ładunku; metoda. ale to wystarczyło dla moich zastosowań.

UWAGA: Dodaję to do posta tutaj, ponieważ nie lubię znajdować problemu i nie mogę znaleźć wszystkich ścieżek do wynikowej odpowiedzi. Jeśli debugger powie ci, aby dodać punkt przerwania do wymienionej funkcji, to gdzieś powinna znaleźć się informacja, aby uzyskać te informacje. Mam nadzieję, że zmniejszy to frustrację niektórych osób próbujących znaleźć tę odpowiedź.

+1

Wspaniała odpowiedź. Dziękujemy za poświęcenie czasu na zebranie tego posta. – Andrew

+1

Ditto. Ten punkt przerwania był wielką pomocą, mimo że mój problem okazał się zupełnie inny. Dzięki za poświęcenie czasu. –

+1

FYI, nie jestem pewien, czy nazwa wyjątku uległa zmianie, czy też moja była w pliku objc, a nie objC++, ale musiałem ustawić punkt przerwania, aby włamał się na __NSAutoreleaseNoPool zamiast objc_autoreleaseNoPool. Mam nadzieję, że pomaga komuś kiedyś. Oryginalny post był jednak bardzo pomocny. – stuckj

1

Wiele metod api kakao zwraca autoreleased obiekty. W szczególności te metody zwracają obiekt, który nie zaczyna się od init, taki jak [NSNumber numberWithLong:]. Jeśli nie masz puli autorelease w miejscu, obiekty te będą wyciekły. Więcej informacji na temat korzystania z NSAutoreleasePool w .

+0

Co to oznacza? Co mogę zrobić, aby rozwiązać ten problem? – Andrew

+0

Dzięki. Przyjrzę się temu – Andrew

+0

po prostu umieść jeden w głównym miejscu, w którym uruchamiasz aplikację i nie musisz się zastanawiać i po prostu użyj piękna, które są automatycznie wydanymi obiektami :) – chikuba

1

Oznacza to, że musisz utworzyć pulę autorelease w wątku, w którym się znajduje. W przeciwnym razie przydzielone obiekty nie zostaną zniszczone (co sugeruje komunikat). Przerwij/zatrzymaj symbol, a następnie przejdź do stosu w wątku (lub programie) i dodaj pulę autorelease. To wszystko.

+0

Pojawia się przed App del. Kończy się, Ale skomentowałem liniowo po linii całą rzecz, a ja wciąż przeciekałem przedmioty. Jakiekolwiek myśli? – Andrew

+0

musisz dodać pulę autorelease. wcześniej w wykonaniu niż punkt wykonywania, w którym punkt przerwania został trafiony. jeśli znajduje się w głównym wątku, dodaj pulę autorelease do 'int main()' (uwaga: twój szablon projektu prawdopodobnie zrobiłby to za Ciebie). w przeciwnym razie zazwyczaj dodajesz go do wpisu wątku. – justin

Powiązane problemy