我有一个连接到附件的应用程序,当我断开附件时,我创建的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保留计数(正如你所期望的那样) BUT 当我只想从init方法获得+2 retainCount时,iniWithAccessory:forProtocol:
给它+3保留计数。
泄漏工具似乎也支持这一点:
逐步查看泄漏工具:
[???Accessory openSession]
- 这是我分配新EASession的地方。[EAInputStream iniWithAccessory:forSession:]
输入流将引用保存回拥有的会话。[EAOutputStream initWithAccessory:forSession:]
输出流将引用保存回拥有会话。[EASession iniWithAccessory:forProtocol:]
我不知道为什么这会增加EASession的保留计数。我认为这是我无法解释的额外保留计数的原因......不确定这应该是如何平衡的。这是Apple的错误,我需要给release
一个额外的时间来平衡事情....非常非常奇怪。[EAInputStream close]
清理上面的步骤#2 [EAOutputStream close]
清理上面的步骤#3 ???Accessory closeSession]
清理上面的步骤#1 所以...为什么我泄漏了EASession对象?使用EASession对象不泄漏的正确方法是什么?
EADemo连接到配件,但它不会泄漏。出于好奇,我添加了额外的[_session retain]
以使其泄漏,因此我可以在乐器中遵循它的malloc历史。有趣的是,在我的应用程序的malloc历史记录中没有调用一些被调用的内部事物。
您可以看到此次调用[EAAccessoryInternal removeSession:]
3次。这在我的应用程序的malloc历史中从未调用过。我认为这是为什么我的EASession没有被释放的关键...
答案 0 :(得分:1)
我知道这个讨论已经很老了,但我最近使用ARC e.t.c时遇到了完全相同的问题。我发现绕过它的一种方法是不关闭输入或输出流。只需要一个处理所有输入e.t.c的类,并根据请求将数据转发给应用程序的其他部分。您可以重新分配初始化EASession对象的init而不会有来自XCode的投诉,因此我假设旧的EASession已被解除批准,因为我的APP不再引用它。 然而,我还没有检查过泄漏。
答案 1 :(得分:1)
虽然演示以相反的方式进行,但我设法通过调用输入和输出关闭方法来解决这个泄漏,从运行循环中删除它们并将其委托设置为nil。