Plik nagłówka dla MTAudioProcessingTap mówi, że jego inicjalizacja i przygotowanie wywołań zwrotnych zostanie zrównoważone przez nieprzygotowanie i sfinalizowanie wywołań zwrotnych. Jednak w Apple's example te wywołania zwrotne nigdy nie są wywoływane (dodałem do nich logowanie, aby sprawdzić). Plik nagłówkowy mówi, że zostaną wywołane, gdy obiekt zostanie zwolniony.Jak zwolnić MTAudioProcessingTap?
W przykładzie Apple, kranik jest przekazywana w parametrze utrzymać w audioMixInputParameters, które są przekazywane w mix audio, gdzie nie jest już publicznie dostępny:
MTAudioProcessingTapRef audioProcessingTap;
if (noErr == MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks, kMTAudioProcessingTapCreationFlag_PreEffects, &audioProcessingTap))
{
audioMixInputParameters.audioTapProcessor = audioProcessingTap;
CFRelease(audioProcessingTap);
audioMix.inputParameters = @[audioMixInputParameters];
_audioMix = audioMix;
}
spodziewałbym AudioMix zatem być odpowiedzialny do zwalniania go we własnej metodzie dealloc i do zwolnienia AudioMix po zwolnieniu powiązanego PlayerItem.
Przykład firmy Apple używa odtwarzacza AVP, który odtwarza tylko jeden element, więc może nie ma potrzeby deallocowania czegokolwiek bezpośrednio. Ale w moim przypadku używam AVQueuePlayer, więc ciągle przekazuję nowe AVPlayerItems. Myślę, że to wyciek z Tapsów, które tworzę dla każdego elementu gracza (wraz z powiązanymi z nim jednostkami dźwiękowymi), mimo że przedmioty gracza są zwalniane.
Jaki jest właściwy sposób na zwolnienie MTAudioProcessingTap i uzyskanie jego nieprzygotowania oraz sfinalizowanie wywołań zwrotnych w celu odpalenia, gdy skończę z powiązanym elementem gracza?
Aktualizacja: Okazało się, że to rzeczywiście jest wciąż dostępny za pośrednictwem Audio Mix, ale uwalniając go tak nie pociąga za sobą unprepare i sfinalizować zwrotnych:
((AVMutableAudioMixInputParameters *)audioMix.inputParameters[0]).audioTapProcessor = nil;
Ani robi to:
MTAudioProcessingTapRef audioProcessingTap = ((AVMutableAudioMixInputParameters *)audioMix.inputParameters[0]).audioTapProcessor;
CFRelease(audioProcessingTap);
Dziękujemy! Dodam, że powoduje to wywołanie callback bez przygotowania (przed sfinalizowaniem). Co więcej, mój playerItem był czasami zwalniany zbyt wcześnie (przed sfinalizowaniem oddzwaniania), więc dodałem silne odniesienie do playerItem w MYAudioTapProcessor i zamiast tego używam tego odnośnika. Więc zastąpiłem '_player.currentItem.audioMix = nil;' z '_audioTapProcessor.playerItem.audioMix = nil;'. – Tenfour04
Dodam też, że nie powinieneś dzwonić do CFRelease'a, jeśli zamierzasz kontynuować korzystanie z AVPlayera, ponieważ kran jest wówczas zbyt długi. Gdy będziesz kontynuować odtwarzanie dźwięku za pomocą nowego dotknięcia, uruchomione zostaną nieprzygotowane i sfinalizowane oddzwanianie. – Tenfour04
Masz rację, zredagowałem moją odpowiedź. – chris