Утечка в [AVPlayer addBoundaryTimeObserverForTimes] - PullRequest
2 голосов
/ 12 ноября 2010

В моем приложении есть экземпляр AVPlayer.Я использую функцию наблюдения за временной границей:

[self setTimeObserver:[player addBoundaryTimeObserverForTimes:watchedTimes
    queue:NULL usingBlock:^{
        NSLog(@"A: %i", [timeObserver retainCount]);
        [player removeTimeObserver:timeObserver];
        NSLog(@"B: %i", [timeObserver retainCount]);
        [self setTimeObserver:nil];
    }]];

Проблема в том, что в соответствии с инструментами я пропускаю некоторые массивы и значения где-то вокруг этого кода.Я проверил счетчик сохранений маркера наблюдения времени, возвращенного AVPlayer в местах, отмеченных A и B в примере кода.В точке A количество сохранений равно 2, в точке B количество сохранений увеличивается до 3 (!).Добавление локального пула автоматического выпуска ничего не меняет.Я знаю, что сохранение количества не является надежной метрикой, но это кажется подозрительным.Любые идеи о том, почему увеличивается количество удержаний или о моих утечках?Трассировка стека в точке утечки выглядит следующим образом:

   0 libSystem.B.dylib calloc
   1 libobjc.A.dylib _internal_class_createInstanceFromZone
   2 libobjc.A.dylib class_createInstance
   3 CoreFoundation __CFAllocateObject2
   4 CoreFoundation +[__NSArrayI __new::]
   5 CoreFoundation -[__NSPlaceholderArray initWithObjects:count:]
   6 CoreFoundation +[NSArray arrayWithObjects:count:]
   7 CoreFoundation -[NSArray sortedArrayWithOptions:usingComparator:]
   8 CoreFoundation -[NSArray sortedArrayUsingComparator:]
   9 AVFoundation -[AVPlayerOccasionalCaller initWithPlayer:times:queue:block:]
  10 AVFoundation -[AVPlayer addBoundaryTimeObserverForTimes:queue:usingBlock:]

Если я правильно понимаю, AVPlayerOccasionalCaller - это «непрозрачный» объект, возвращаемый addBoundaryTimeObserverForTimes:queue:usingBlock:, или наблюдателем времени.

1 Ответ

2 голосов
/ 13 ноября 2010

Не использовать -retainCount.

Абсолютное количество сохраняемых объектов не имеет смысла.

Вы должны вызывать release ровно столько раз, сколько вы вызывали сохранение объекта. Не меньше (если вам не нравятся утечки) и, конечно же, не больше (если вам не нравятся сбои).

Подробнее см. Рекомендации по управлению памятью .

<Ч />

В этом конкретном случае счет сохранения, который вы печатаете, совершенно не имеет значения. removeTimeObserver: вероятно сохраняет и автоматически освобождает объект. Не имеет значения; это деталь реализации.

При использовании шаблона Leaks в приборе обратите внимание, что прибор Allocations настроен на запись количества ссылок. Когда вы обнаружили «утечку», посмотрите на список событий подсчета ссылок для этого объекта. Вероятно, будет стек, в котором некоторый ваш код вызывает дополнительное сохранение. Если нет, то это может быть ошибка в фреймворке.

...