EASession Утечки

У меня есть приложение, которое подключается к аксессуару, и сеанс EASession, который я создаю для связи с утечками аксессуара, когда вы отключаете аксессуар.

Когда аксессуар подключается, я получаю уведомление об этом и проверяю коллекцию аксессуаров EAAccessoryManager для аксессуара с определенным именем, использующего определенный протокол. Когда я нахожу это, я создаю объект EASession для этого аксессуара с кодом:

-(void) openSession
{
   ...  // finds accessory object

   if (accessory)
   {
      [self closeSession];
      session = [EASession alloc];
      NSLog(@"alloc :: session retainCount: %i", session.retainCount);
      [session initWithAccessory:accessory forProtocol:SmokeSignalsProtocolName]; 
      NSLog(@"init  :: session retainCount: %i", session.retainCount);

      [[session inputStream] open]; 
      [[session outputStream] open]; 

      ... // other logic (pump run loop, etc..)
   }
}

-(void) closeSession
{
    if (session)
    {
       [[session inputStream] close]; 
       [[session outputStream] close]; 
       [session release], session = nil;
    }
}

Обычно у меня есть alloc и init в одной строке, но я обнаружил (выделяя это следующим образом), что alloc дает +1 retain count (как и следовало ожидать), НО iniWithAccessory:forProtocol: дает ему +3 retain count, когда я ожидаю только +2 retainCount от метода init.

Инструмент утечки также, кажется, поддерживает это:

Шаг за шагом посмотрим на утечки прибора:

  1. +1 сохранить счет:: [???Accessory openSession] - это то место, где я размещаю новую EASession.
  2. +1 сохранить счет:: [EAInputStream iniWithAccessory:forSession:] Входной поток содержит ссылку обратно на сеанс владельца.
  3. +1 сохранить счет:: [EAOutputStream initWithAccessory:forSession:] Выходной поток содержит ссылку на сеанс владельца.
  4. +1 сохранить счет:: [EASession iniWithAccessory:forProtocol:] Я понятия не имею, почему это увеличивает количество сохраняемых EASession. Я считаю, что это ответственно за дополнительный счет удержания, который я не могу объяснить... Не уверен, как это должно быть сбалансировано. Это ошибка Apple, и мне нужно позвонить release дополнительное время, чтобы сбалансировать вещи.... очень очень странно.
  5. -1 сохранить счет:: [EAInputStream close] Очищает шаг № 2 выше
  6. -1 сохранить счет:: [EAOutputStream close] Очищает шаг № 3 выше
  7. -1 сохранить счет:: ???Accessory closeSession] Очищает шаг № 1 выше1

Итак... Почему я пропускаю объект EASession? Как правильно использовать объект EASession, чтобы не утечка?


Редактировать - EADemo не течет, но...

EADemo подключается к аксессуарам, но не протекает. Из любопытства я добавил дополнительный [_session retain] чтобы он просочился, чтобы я мог следить за историей malloc в инструментах. Было интересно увидеть некоторые внутренние вещи, которые не назывались в истории malloc моего приложения.

Вы можете увидеть это имеет [EAAccessoryInternal removeSession:] звонил 3 раза. Это никогда не называлось в истории malloc моего приложения. Я думаю, что это ключ к тому, почему моя EASession не выходит...

2 ответа

В то время как демонстрация делает это наоборот, мне удалось исправить эту утечку, вызвав методы закрытия ввода и вывода после удаления их из цикла выполнения и установки их делегата равным nil.

Я знаю, что это обсуждение довольно старое, но недавно у меня была точно такая же проблема с использованием ARC и т. Д. Я обнаружил, что одним из способов решения этой проблемы является просто не закрывать потоки ввода или вывода. Просто имейте класс, который обрабатывает все входные данные и т. Д. И отправляйте данные по запросу в другие части вашего приложения. Вы можете перераспределить init объект EASession без нареканий со стороны XCode, поэтому я предполагаю, что старая EASession отменена, так как на нее больше не ссылается мое приложение. Однако я еще не проверил утечки.

Другие вопросы по тегам