我有一个连接到附件的应用程序,当断开附件时,我创建的用于与附件通信的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放在一行上,但是我发现(这样分离出来)的是,分配给+1保留计数(如您所愿)但是
iniWithAccessory:forProtocol:
给它+3保留当我只希望init方法获得+2 keepCount时计数。泄漏仪器似乎也支持这一点:
逐步查看泄漏仪器:
[???Accessory openSession]
-这是我分配新的EASession的地方。 [EAInputStream iniWithAccessory:forSession:]
输入流保留对拥有会话的引用。 [EAOutputStream initWithAccessory:forSession:]
输出流保留对拥有会话的引用。 [EASession iniWithAccessory:forProtocol:]
我不知道为什么这会增加EASession的保留计数。我认为这是造成我无法解释的额外保留人数的原因...不知道应该如何平衡。这是苹果的bug吗,我需要额外打电话给release
来平衡事物...。非常奇怪。 [EAInputStream close]
清理[EAOutputStream close]
清理???Accessory closeSession]
清理上面的步骤#1 那么...为什么我泄漏EASession对象?使用EASession对象不泄漏的正确方法是什么?
编辑-EADemo不会泄漏,但是...
EADemo连接到附件,但不会泄漏。出于好奇,我添加了一个额外的
[_session retain]
使其泄漏,因此我可以在乐器中跟踪它的malloc历史记录。有趣的是,我的应用程序的malloc历史记录中没有调用一些内部调用。您可以看到
[EAAccessoryInternal removeSession:]
被调用了3次。在我的应用程序的malloc历史记录中从未调用过此方法。我认为这是为什么不发布我的EASession的关键... 最佳答案
我知道现在的讨论已经很久了,但是最近使用ARC e.t.c遇到了同样的问题。我发现解决它的一种方法是不关闭输入或输出流。只需拥有一个可处理所有输入e.t.c的类,然后根据请求将数据转发到应用程序的其他部分。您可以重新分配EASession对象,而不会受到XCode的抱怨,所以我认为旧的EASession已被释放,因为我的APP不再引用它。
我还没有检查泄漏。