AVAudioPlayer zgłasza punkt przerwania w trybie debugowania

108

Za każdym razem, gdy ładuję aplikację, zatrzymuje się, tak jakbym ustawił punkt przerwania w tej linii:

self.audioPlayer = 
 [[[AVAudioPlayer alloc] initWithData:[dataPersister loadData:self.fileName] 
                                error:&outError] autorelease];

Nie ma punktu przerwania powyżej ani żadnego miejsca w pobliżu tej linii. Dzieje się tak tylko wtedy, gdy uruchamiam aplikację w trybie debugowania i nic nie ulega awarii po punkcie przerwania. Aplikacja działa tak, jakby nic się nie działo po kliknięciu przycisku „Kontynuuj wykonywanie programu”.

To jest metoda loadData, która jest wywoływana z initWithData:

-(NSData*)loadData:(NSString*)fileName
{
    NSString *dataPath = [self.path stringByAppendingPathComponent:fileName];
    dataPath = [dataPath stringByStandardizingPath];
    NSData *data = [[[NSData alloc] initWithContentsOfFile:dataPath]autorelease ];
    return data;
}

Wydaje się, że funkcja loadData działa poprawnie. Żądany plik mp3 jest ładowany i odtwarzany bez żadnych problemów po punkcie przerwania.

Czy masz pojęcie, co robię źle?

EDYCJA: Uruchomiłem śledzenie cofania, gdy zatrzymuje się w punkcie przerwania. To był wynik:

(lldb) bt
* wątek # 1: tid = 0x1c03, 0x30df1724 libc ++ abi.dylib`__cxa_throw, zatrzymaj powód = punkt przerwania 1.2
    ramka # 0: 0x30df1724 libc ++ abi.dylib`__cxa_throw
    ramka # 1: 0x36403a24 AudioToolbox`ID3ParserHandle :: ID3ParserHandle (void *, long (*) (void *, unsigned long, unsigned long, unsigned long, void **, unsigned long *)) + 452
    ramka nr 2: 0x36403b0e AudioToolbox`ID3ParserOpen + 142
    ramka # 3: 0x3635bd16 AudioToolbox`MPEGAudioFile :: ParseID3Tags () + 58
    ramka # 4: 0x3635b9aa AudioToolbox`MPEGAudioFile :: ParseAudioFile () + 26
    ramka # 5: 0x3631723e AudioToolbox`AudioFileObject :: DoOpenWithCallbacks (void *, long (*) (void *, long long, unsigned long, void *, unsigned long *), long (*) (void *, long long, unsigned long , void const *, unsigned long *), long long (*) (void *), long (*) (void *, long long)) + 166
    ramka # 6: 0x36316480 AudioToolbox`AudioFileOpenWithCallbacks + 612
    ramka # 7: 0x31f4c1ec AVFoundation`- [AVAudioPlayer initWithData: błąd:] + 120

„ROZWIĄZANIE”: Okazuje się, że jeśli wyłączę punkt przerwania wyjątku dla wszystkich wyjątków i użyję punktu przerwania tylko dla wyjątków celu-C, problem znika. Ale to nie rozwiązuje problemu polegającego na tym, że alokacja AVAudioPlayer generuje wyjątek C ++.

ThomasCle
źródło
2
Miałem ten sam ślad stosu. Wyłączenie punktu przerwania „Wszystkie wyjątki” uniemożliwiło mi to.
makdad

Odpowiedzi:

175

Dodaj punkt przerwania wyjątku i edytuj typ wyjątku z „Wszystkie” na „Wyjątki celu-C”

Niektóre klasy w AudioToolbox generują zwykłe wyjątki C ++. Możesz je w ten sposób odfiltrować.

Mugunth
źródło
6
Ponieważ w swoim pytaniu napisałem sekcję „ROZWIĄZANIE”, nie uważam tego za rozwiązanie. Nie AVAudioPlayerpowinien generować losowych wyjątków.
ThomasCle
10
„AVAudioPlayer nie powinien rzucać przypadkowych wyjątków” - to nie jest w naszych rękach. Tak właśnie jest napisane framework i musisz z nim żyć. Chociaż zgadzam się, że to nie jest dobry pomysł
Mugunth
@Mugunth Czy to oznacza, że ​​framework reaguje na wewnętrzne błędy i je koryguje? Czy znasz jakieś inne dokumenty na ten temat? Nie mogę znaleźć wiele w Internecie, co sugeruje mi, że może to być spowodowane błędem programisty ...
Remover
21

AVAudioPlayer i AVAudioRecorder będą rzucać wyjątki, kilka z nich. Są one obsługiwane wewnętrznie przez graczy, ale jeśli masz punkt przerwania dla „Wszystkich punktów przerwania” (tj. Wyjątek: Wszystkie, Przerwa: Przy rzucie), złapiesz te wyjątki. Jeśli będziesz kontynuować wykonywanie na nich, aplikacja będzie nadal działać normalnie i nie ulegnie awarii.

Jedynym rozwiązaniem, które do tej pory wymyśliłem, jest kliknięcie paska punktu przerwania w Nawigatorze punktów przerwania, wyłączenie tego konkretnego punktu przerwania i uruchomienie go z wyłączonym.

Kiedy / jeśli aplikacja kiedykolwiek ulegnie awarii z rzuconym wyjątkiem, używam cmd-6, włączam ten punkt przerwania i ponownie uruchamiam i robię wszystko, co zrobiłem, gdy się zawiesił.

Edycja: ustawienie na „Wyjątki celu-C” jest oczywiście sposobem na zrobienie tego. Zobacz powyższą odpowiedź!

Kalle
źródło
9

Oto zrzut ekranu pokazujący, jak naprawiłem ten błąd. Nie jestem pewien, czy jest to ten sam sposób, o którym mówią powyższe odpowiedzi, ale zakładam, że jest podobnie.

  1. Przejdź do nawigatora punktów przerwania w Xcode.
  2. Kliknij z klawiszem Control w wierszu „Wszystkie wyjątki”.
  3. Wybierz opcję „Edytuj punkt przerwania…”.
  4. Zmień Exceptionod Allna Objective-C.

wprowadź opis obrazu tutaj

Stewart Macdonald
źródło
2

Śledzenie wstecz bardzo pomogło, dzięki !. Niedawno zaczęliśmy napotykać ten sam problem. Okazuje się, że pliki mp3, na które rzucał, nie miały prawidłowego tagu ID3 i uruchomienie ich przez aplikację taką jak Tagr naprawiło je od razu!

yo.ian.g
źródło
1
Po ustawieniu brakujących pól w tagu ID3, aplikacja nie zatrzymywała się już na inicjalizacji AVAudioPlayer, ale nadal zatrzymywała się na instrukcji odtwarzania ...
Reinhard Männer
Które pola były wymagane? Wszyscy?
reggian
@Reggian Nie przypominam sobie, to było tak dawno temu. Przepraszam za to! Nie pamiętam, żebym musiał dodawać brakujące pola, wystarczyło przepuścić go przez środek odkażający znaczniki, jeśli dobrze pamiętam!
yo.ian.g
2

W Xcode 9.2 możesz wyłączyć określone wyjątki po ich zobaczeniu. Otwórz menu punktów przerwania i kliknij, aby wyłączyć (wyblakła strzałka)

wprowadź opis obrazu tutaj

quantumpotato
źródło
-4

Spróbuj ustawić AVAudioPlayer jako zmienną klasową!

redestructa
źródło
1
W moim przypadku ustawiłem już AVAudioPlayer jako zmienną klasy i nadal nie działa. Wygląda na to, że tak naprawdę nie znałeś rozwiązania
Alex Cio