我有一个连接到附件的应用程序,当您断开附件时,我创建的用于与附件通信的 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 保留计数(如您所料)但是当iniWithAccessory:forProtocol:
我给它 +3 保留计数只会期望 init 方法中的 +2 retainCount。
泄漏工具似乎也支持这一点:
一步一步看泄漏仪器:
- +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]
清理上面的步骤 #11
那么...为什么我要泄漏 EASession 对象?使用 EASession 对象不泄漏的正确方法是什么?
编辑 - EADemo 不会泄漏,但...
EADemo连接到配件,但不会泄漏。出于好奇,我添加了一个额外[_session retain]
的内容以使其泄漏,以便我可以在仪器中跟踪它的 malloc 历史。有趣的是,我的应用程序的 malloc 历史记录中没有调用一些内部调用。
你可以看到这已经[EAAccessoryInternal removeSession:]
调用了 3 次。这在我的应用程序的 malloc 历史中从未被调用过。我认为这是为什么我的 EASession 没有被释放的关键......