У меня есть приложение, которое подключается к аксессуару, и 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 keepcount (, как и следовало ожидать, ), НО iniWithAccessory:forProtocol:
дает ему +3 keepcount, тогда как я ожидал бы только +2 keepCount от метода init.
Похоже, что инструмент утечек также поддерживает это.:
Пошаговый взгляд на инструмент утечек:
[???Accessory openSession]
-здесь я выделяю новую сессию EASession.[EAInputStream iniWithAccessory:forSession:]
Входной поток удерживает ссылку на сеанс-владелец.[EAOutputStream initWithAccessory:forSession:]
Выходной поток содержит ссылку на сеанс-владелец.[EASession iniWithAccessory:forProtocol:]
Я понятия не имею, почему это увеличивает количество сохранений EASession. Я считаю, что это отвечает за дополнительный счетчик удержания, который я не могу объяснить... Не уверен, как это должно быть сбалансировано. Является ли это ошибкой Apple, и мне нужно позвонить по номеру release
еще раз, чтобы сбалансировать ситуацию.... Очень, ОЧЕНЬ странно.[EAInputStream close]
Этап очистки #2 выше[EAOutputStream close]
Очистка шага #3 выше???Accessory closeSession]
Этап очистки #1 выше1Итак... Почему я пропускаю объект EASession? Как правильно использовать объект EASession, чтобы избежать утечки?
EADemo подключается к аксессуарам, но не протекает. Из любопытства я добавил дополнительный [_session retain]
, чтобы сделать его утечкой, чтобы я мог следить за историей использования malloc в инструментах. Было интересно увидеть некоторые внутренние вещи, которые не были вызваны в истории malloc моего приложения.
Вы можете видеть, что [EAAccessoryInternal removeSession:]
звонили 3 раза. Это никогда не вызывалось в истории malloc моего приложения. Я думаю, это ключ к тому, почему моя сессия EASession не выпускается...