【问题标题】:EASession LeaksEASession 泄漏
【发布时间】:2012-05-04 12:51:41
【问题描述】:

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

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

逐步查看泄漏仪器:

  1. +1 保留计数 ::[???Accessory openSession] - 这是我分配新 EASession 的地方。
  2. +1 保留计数 ::[EAInputStream iniWithAccessory:forSession:] 输入流保存对拥有会话的引用。
  3. +1 保留计数 ::[EAOutputStream initWithAccessory:forSession:] 输出流保存对拥有会话的引用。
  4. +1 保留计数 ::[EASession iniWithAccessory:forProtocol:] 我不知道为什么这会增加 EASession 的保留计数。我相信这是造成我无法解释的额外保留计数的原因......不确定这应该如何平衡。这是 Apple 的错误吗?我需要给release 打个电话来平衡一下……非常非常奇怪。
  5. -1 保留计数 :: [EAInputStream close] 清理上面的第 2 步
  6. -1 保留计数 :: [EAOutputStream close] 清理上面的第 3 步
  7. -1 保留计数 :: ???Accessory closeSession] 清理上面的步骤 #11

那么...为什么我要泄漏 EASession 对象?使用 EASession 对象不泄漏的正确方法是什么?


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

EADemo 连接配件,但不漏电。出于好奇,我添加了一个额外的 [_session retain] 以使其泄漏,以便我可以在仪器中跟踪它的 malloc 历史。有趣的是,我的应用程序的 malloc 历史记录中没有调用一些内部调用。

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

【问题讨论】:

标签: ios memory-leaks external-accessory eaaccessory


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2011-11-02
      • 1970-01-01
      • 2016-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      • 2010-12-16
      相关资源
      最近更新 更多