EASession Leaks

时间:2012-04-23 21:22:49

标签: ios memory-leaks external-accessory eaaccessory

我有一个连接到附件的应用程序,当我断开附件时,我创建的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保留计数。

泄漏工具似乎也支持这一点:

enter image description here

逐步查看泄漏工具:

  1. +1保留计数:: [???Accessory openSession] - 这是我分配新EASession的地方。
  2. +1 retain count :: [EAInputStream iniWithAccessory:forSession:]输入流将引用保存回拥有的会话。
  3. +1 retain count :: [EAOutputStream initWithAccessory:forSession:]输出流将引用保存回拥有会话。
  4. +1保留计数:: [EASession iniWithAccessory:forProtocol:]我不知道为什么这会增加EASession的保留计数。我认为这是我无法解释的额外保留计数的原因......不确定这应该是如何平衡的。这是Apple的错误,我需要给release一个额外的时间来平衡事情....非常非常奇怪。
  5. -1 retain count :: [EAInputStream close]清理上面的步骤#2
  6. -1 retain count :: [EAOutputStream close]清理上面的步骤#3
  7. -1 retain count :: ???Accessory closeSession]清理上面的步骤#1
  8. 所以...为什么我泄漏了EASession对象?使用EASession对象不泄漏的正确方法是什么?


    编辑 - EADemo不泄漏,但......

    EADemo连接到配件,但它不会泄漏。出于好奇,我添加了额外的[_session retain]以使其泄漏,因此我可以在乐器中遵循它的malloc历史。有趣的是,在我的应用程序的malloc历史记录中没有调用一些被调用的内部事物。

    enter image description here

    您可以看到此次调用[EAAccessoryInternal removeSession:] 3次。这在我的应用程序的malloc历史中从未调用过。我认为这是为什么我的EASession没有被释放的关键...

2 个答案:

答案 0 :(得分:1)

我知道这个讨论已经很老了,但我最近使用ARC e.t.c时遇到了完全相同的问题。我发现绕过它的一种方法是不关闭输入或输出流。只需要一个处理所有输入e.t.c的类,并根据请求将数据转发给应用程序的其他部分。您可以重新分配初始化EASession对象的init而不会有来自XCode的投诉,因此我假设旧的EASession已被解除批准,因为我的APP不再引用它。 然而,我还没有检查过泄漏。

答案 1 :(得分:1)

虽然演示以相反的方式进行,但我设法通过调用输入和输出关闭方法来解决这个泄漏,从运行循环中删除它们并将其委托设置为nil。