#ios5 #mpmovieplayercontroller
#ios5 #mpmovieplayercontroller
Вопрос:
Когда я пытаюсь воспроизвести видео с моего iPhone (расположенного в documentsDirectory), я получаю следующую ошибку, используя iOS 5, в то время как он нормально работал с iOS 4.3:
Экземпляр 0x168da0 класса AVPlayerItem был освобожден, в то время как наблюдатели значений ключа все еще были зарегистрированы в нем. Произошла утечка информации о наблюдении, и она даже может быть ошибочно прикреплена к какому-либо другому объекту. Установите точку останова в NSKVODeallocateBreak, чтобы остановить здесь в отладчике. Вот текущая информация о наблюдении: (Контекст: 0x0, свойство: 0x10b570> Контекст: 0x0, свойство: 0x117ab0>
Вот выдержка из кода:
MPMoviePlayerController *moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:[appDelegate.mediaManager loadVideo:[element valueForAttributeNamed:@"value"]]];
//create a NSNotificationCenter which call moviePlaybackComplete function when video playback finished
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlaybackComplete:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayerController];
//display the moviePlayer view
[self.view addSubview:moviePlayerController.view];
moviePlayerController.fullscreen = YES;
[moviePlayerController play];
Ответ №1:
РЕДАКТИРОВАТЬ: сразу после публикации ответа ниже я заметил, что всякий раз, когда контроллер был перераспределен, ошибки возвращались, поскольку старый контроллер автоматически освобождался, даже если я сам не настраивал никаких обработчиков уведомлений. Поскольку сбои происходят из кода внутри платформы MP, я бы сказал, что это, похоже, ошибка операционной системы.
Я столкнулся с той же проблемой с проектом iOS 5 на основе раскадровки, использующим ARC. Проблема заключается в использовании временной переменной в стеке для ссылки на контроллер movie — в моем случае я предполагал взаимодействие с ARC, но это может быть более фундаментальным, чем это. В любом случае, похоже, что что-то освобождается / теряется слишком рано (например, при возникновении ошибки воспроизведения), и журнал заполняется тем видом вывода, который вы описываете.
Сохранение ссылки на контроллер фильма в свойстве, определенном в классе-владельце, решило эту проблему в моем случае; то есть:
@interface MyClass
@property ( strong, nonatomic ) MPMoviePlayerViewController * movieController;
@end
@@implementation MyClass
@synthesize movieController = _movieController;
// ...then later, this:
//
// MPMoviePlayerController *moviePlayerController = [...];
//
// ...becomes:
self.movieController = [...];
Если вы используете синтезированные средства доступа для свойства, то независимо от того, используете ли вы ручной или автоматический подсчет ссылок, сгенерированный метод настройки должен корректно освободить старый контроллер movie (если он есть) перед настройкой нового.
В качестве примечания, если вы (скажем) освободите / ‘unreference’ (установите значение nil) свойство вручную в MPMoviePlayerPlaybackDidFinishNotification
обработчике уведомлений, вы, вероятно, заметите, что ошибки возвращаются. Так что не делайте этого 🙂
Комментарии:
1. Это старая версия, но на всякий случай, если у кого-то есть такая же проблема, MPMoviePlayerController, похоже, не нравятся определенные NSURLS, даже если они считаются допустимыми объектами. «Секрет» заключается в том, чтобы получить путь к файлу в виде NSString, а затем использовать
[NSURL fileURLWithPath:URLStringPath]
для создания URL-адресов, которые вы используете для созданияMPMoviePlayerController
экземпляра.2. Вы сэкономили мне бесчисленное количество времени. Отличная работа по исследованию этого. Я рвал на себе волосы.
Ответ №2:
Ах. Вы наблюдаете объект TekkPoint из объекта SomethingElse, а объект SomethingElse — это тот, который добавляет и удаляет наблюдателей, правильно? (Это обычный способ выполнения; я просто пытаюсь уточнить.)
Похоже, что ваш объект TekkPoint освобождается, в то время как SomethingElse, который наблюдает за ним, все еще существует. Метод SomethingElse dealloc не вызывается, потому что освобождается точка Текка, а не SomethingElse.
Если вы планируете наблюдать объект, который может исчезнуть до исчезновения наблюдателя, то вам нужен какой-то способ уведомления наблюдателей о том, что они должны удалить своих наблюдателей. Ваша TekkPoint может иметь свойство alive, которое также будет наблюдаться SomethingElse, и когда для него будет установлено значение NO, тогда все, кто наблюдает за TekkPoint, удалят себя как наблюдателя.
Ответ №3:
У меня была такая же ошибка раньше, и просто удалите наблюдателя, когда просмотр исчезнет, устранит утечку.
Поместить
[[NSNotificationCenter defaultCenter] removeObserver:self];
в willWillDisappear
или dealloc
Комментарии:
1. NSNotificationCenter != KVO. Вы смешиваете две совершенно разные технологии.
2. он спрашивал о
MPMoviePlayerPlaybackDidFinishNotification
том, что это не KVO3. Исчезнет ли он? Вы имеете в виду viewWillDisappear? 🙂
4. неправильный ответ на приведенный выше вопрос. пожалуйста, четко прочитайте вопрос