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