I get an EXC_BAD_ACCESS error after returning from the thread method in which I configured NSAutoreleasePool. The place of failure occurs when NSRunLoop is called. I am trying to wrap a third-party library consisting mainly of a class (let it be called the Connection class) and its delegate in such a way that it will behave synchronously, and not asynchronously, to client classes. The packaging class, called NFCConnection, conforms to the delegate protocol and is passed to the Connection setDelegate method in the NFCConnection constructor.
The method in which I create a new thread is as follows:
- (void)methodA { [NSThread detachNewThreadSelector:@selector(doSomethingImportant) toTarget:self withObject:nil]; while (!callBackInvoked) { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
The stream method, doSomethingImportant, looks like this:
- (void)doSomethingImportant { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [[Connection instance] somethingImportant]; [pool release]; }
A call to Connection somethingImportant will call a call to one of the delegate methods in the main thread. In each of these callback methods, I set the variable callBackMethod to NO, causing the while loop in method A to exit. The error occurs after doSomethingImportant returns, but before calling one of the delegate methods. The EXC_BAD_ACCESS error occurs when calling NSRunLoop. Here is part of the stack trace:
#0 0x3138cec0 in objc_msgSend #1 0x000100ac in -[Connection ProcessRx_Api_SomethingImportant:] at Connection.m:621 #2 0x000114fa in +[Connection ProcessRx:] at Connection.m:900 #3 0x00012758 in -[CommHandling ProcessRx:length:] at CommHandling.m:294 #4 0x000126b8 in -[CommHandling stream:handleEvent:] at CommHandling.m:331 #5 0x30a7b958 in -[EAInputStream _streamEventTrigger] #6 0x30a7be78 in __streamEventTrigger #7 0x323f53a6 in CFRunLoopRunSpecific #8 0x323f4c1e in CFRunLoopRunInMode #9 0x3373c966 in -[NSRunLoop(NSRunLoop) runMode:beforeDate:] #10 0x0000ae66 in -[NFCConnection methodA:] at NFCConnection.m:137 #11 0x0000bbf2 in -[NFCTestViewController doIt] at NFCTestViewController.m:39 ...
Now I can prevent the error altogether, and the wrapped API seems to work synchronously if I neglect the autoplay pool setting in doSomethingImportant. But if I did, the console would print the following:
2010-08-09 14:54:49.259 ConnetionTest[3353:652f] *** _NSAutoreleaseNoPool(): Object 0x1928b0 of class __NSCFDate autoreleased with no pool in place - just leaking Stack: (0x3374ff83 0x33723973 0x3372393f 0x323f78f1 0x3372b913 0x10221 0xc833 0xb045 0x33731acd 0x336dfd15 0x33ad8788) 2010-08-09 14:54:49.272 ConnetionTest[3353:652f] *** _NSAutoreleaseNoPool(): Object 0x18f800 of class NSCFTimer autoreleased with no pool in place - just leaking Stack: (0x3374ff83 0x33723973 0x3372393f 0x3372b93b 0x10221 0xc833 0xb045 0x33731acd 0x336dfd15 0x33ad8788)
Are these messages above caused by not being issued in an instance of the Connection class? I am creating an NSDate but not an instance to be released. Same thing with NSTimer.
I am trying to do everything right by installing NSAutoreleasePool, but it looks like I'm doing something wrong. However, I do not know what it can be. Any help is much appreciated!
Rich
multithreading objective-c nsrunloop nsautoreleasepool
richever
source share