iOS 6.0 GM关闭会话时出现EAAcessory错误

13

有一个MFI设备通过蓝牙(2.1+EDR)连接到iPhone 4S(6.0 GM)或iPad(6.0 GM)。该项目是在Xcode 4.5 GM上构建的。当应用程序收到EAAccessoryDidDisconnectNotification时,它会发送消息[_eaSessionController closeSession];。这些在iOS 5.1.1或更早期版本中运行良好。但是在iOS 6上,使用此消息后,我得到了以下日志:

-[NSCondition dealloc]: condition (<NSCondition: 0x2e5640> '(null)') deallocated while still in use
Break on _NSLockError() to debug.

有什么想法吗?


我和你处于同样的情况。我们有一个低功耗蓝牙设备,它会定期连接和断开。当手机物理连接到调试器时,如果应用程序在后台运行,日志中会出现错误。如果没有连接到调试器,它就会崩溃。你向苹果公司报告了这个问题吗? - Paul Sylliboy
2
不,我没有向苹果报告这个问题。>> “低功耗蓝牙设备”您是指“蓝牙4.0低能耗”吗? - Yauheni Shauchenka
不是蓝牙4.0,我想是2.1版本。它会自动断开和重新连接,我只是使用连接通知来触发我的读写操作,但写回去会导致它断开连接。 - Paul Sylliboy
3个回答

4

iOS 6.1+没有这样的问题。要解决iOS 6.0和iOS 6.0.1的问题,请使用以下解决方法:

请注意: 这只是临时解决方案,使您的iOS 6.0和6.0.1用户可以继续使用您的应用程序。

有一个简单的技巧可以避免应用程序崩溃: 只需创建一个新类别并覆盖dealloc方法(NSCondition)适用于iOS 6.0和iOS 6.0.1:

#import "NSCondition+LeakDealloc.h"
#import <objc/runtime.h>

@implementation NSCondition (LeakDealloc)

- (void) safeDealloc
{
    float sVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (sVersion < 6.0 || sVersion >= 6.1)
    {
        [self safeDealloc];
    }
}

+ (void) load 
{
    method_exchangeImplementations(class_getInstanceMethod(self, @selector(dealloc)), class_getInstanceMethod(self, @selector(safeDealloc)));
}

@end

这个解决方案会导致新的泄漏,在经过20分钟的测试和大约50次后台/前台切换之后,仪器显示出10个NSCondition泄漏(960字节),但没有崩溃!


1
嗨。至少在iOS 6.0.1上我没有这个问题,但是在iOS 6.1.X上却有相同的问题。实际上,它会在NSRecursiveLock dealloc时崩溃。我的第一个解决方法是“关闭会话时不要将其设置为nil”。我也尝试了你的解决方案,使用类别也可以解决。苹果开发者论坛上有一篇关于这个问题的帖子,并且有一个错误已经被打开(https://devforums.apple.com/message/789466#789466)。我真的很惊讶这个错误仍然存在,而且网络上没有太多反馈。我们是少数人,还是在处理会话时做错了什么? - ipodishima
在我的情况下,我们只有在一些不受欢迎的过渡版本中才会崩溃。但是对于流行的iOS版本,一切都正常工作。看起来就是这样。请随时让我们知道您的错误报告状态。 - Yauheni Shauchenka

4
我遇到了同样的问题。当调用 [NSStream close] 时接收 EAAccessoryDidDisconnectNotification 通知时会出现此警告。在断开连接之前,应该还有两台设备之间的一些数据交换。
打断点在 _NSLockError 上,将显示在对象被释放时,外部配件框架生成的某些线程正在等待条件。其中一个线程肯定正在等待被释放的条件,这就解释了控制台上抛出的警告。
我还注意到,每次配件断开连接然后重新连接时,外部配件框架创建的线程数量不断增加,它们似乎只是泄漏。
在我看来,外部配件框架以某种方式未能正确释放其分配的资源,这导致了很多混乱。其中一个随后的影响是在调用 OSAtomicCompareAndSwap64 期间,在这些泄漏的线程中发生崩溃。
我使用基本示例重现了此问题,在该示例中,流已安排在主线程上,以避免应用程序内部的任何线程管理。我相信这是 iOS 6 上配件管理错误,苹果公司应该知道。我会报告这个问题并等待他们的回复。
同时,我想知道你们中是否有人取得了任何进展。
谢谢,

我还没有进一步处理这个问题。我想我也会提交一个错误报告。希望这能帮助推动他们更快地解决问题。不过,我已经看到了泄漏的线程问题,并为此开始了支持工单。他们让我提交了一个错误报告,并向他们发送了一个设备进行测试。前几天我被告知他们已经意识到并理解了这个问题。他们只是没有说是否以及何时会解决它。如果我要猜测,他们可能会在iOS 6中修复它。 - Paul Sylliboy
谢谢Paul的更新。我猜你是指iOS 6.1,因为这个问题已经存在于iOS 6.0下 :) - Hichem BOUSSETTA

1
问题已在iOS 6.1中得到修复。 不再泄漏NSCondition或外部附件线程。苹果似乎已经彻底解决了这个问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接