Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EAAcessory errors while closing session with iOS 6.0 GM

There is a MFI device that is connected to iPhone 4S (6.0 GM) or to iPad (6.0 GM) via Bluetooth (2.1 + EDR). The project was built on Xcode 4.5 GM. When the app gets EAAccessoryDidDisconnectNotification it will send message [_eaSessionController closeSession];. All these worked nice in iOS 5.1.1 or earler. But on iOS6 with this message I got logs as follows:

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

Any ideas?

like image 646
Yauheni Shauchenka Avatar asked Sep 17 '12 09:09

Yauheni Shauchenka


Video Answer


2 Answers

I came across the same issue. This warning is thrown when calling [NSStream close] upon receiving an EAAccessoryDidDisconnectNotification. There should be also some data exchange between the two devices just before the disconnection.

Breaking on _NSLockError will show that at the moment the object is deallocated, some of the threads spawned by the external accessory framework are waiting on conditions. One of those certainly waits on the condition that is being freed, which explains the warning thrown on the console.

I also noticed that the number of threads created by the external accessory framework keeps on growing each time the accessory disconnects then connects, and they seem to be just leaking.

It seems to me that somehow, the external accessory framework does not properly free the resources it allocates, which results in a lot of mess. One of the subsequent effects of this are crashes that happen inside one of those leaked threads during a call to OSAtomicCompareAndSwap64.

I managed to reproduce the issue using a basic sample in which the streams are scheduled on the main thread to avoid any thread management inside the application. I believe it's an accessory management bug on iOS 6 that Apple should be aware of. I'll report it and wait for what they have to say.

Meanwhile, I wonder if anyone of you guys has managed to make any progress on this.

Thanks,

like image 158
Hichem BOUSSETTA Avatar answered Oct 02 '22 16:10

Hichem BOUSSETTA


There is no such trouble in iOS 6.1+. To fix this for iOS 6.0 and iOS 6.0.1 please use next solution:

Please note: this is only temp solution allow your users with iOS 6.0 and 6.0.1 continue use your app.

There is a simple hack to avoid application crashes: just create new category and override dealloc method (NSCondition) for iOS 6.0 and 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

This solution make new leak, after 20 min tests and about 50 BG/FG swithces instruments shows 10 NSCondition leaks (960 Bytes), BUT no one crash!

like image 22
Yauheni Shauchenka Avatar answered Oct 02 '22 16:10

Yauheni Shauchenka