从设置了 NSAutoreleasePool 的线程方法返回后,我收到 EXC_BAD_ACCESS 错误。失败的地方是调用 NSRunLoop。我正在尝试包装一个主要由一个类(我们称其为 Connection 类)及其委托组成的第 3 方库,以便它与客户端类同步而不是异步运行。名为 NFCConnection 的包装类符合委托协议,并在 NFCConnection 的构造函数中传递给 Connection 的 setDelegate 方法。
我创建新线程的方法如下:
- (void)methodA {
[NSThread detachNewThreadSelector:@selector(doSomethingImportant)
toTarget:self
withObject:nil];
while (!callBackInvoked) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode // Error!
beforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
}
}
线程方法 doSomethingImportant 如下所示:
- (void)doSomethingImportant {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[Connection instance] somethingImportant];
[pool release];
}
对 Connection 的 somethingImportant 的调用将导致在主线程上调用委托方法之一。在每个回调方法中,我将变量 callBackMethod 设置为 NO,导致方法 A 中的 while 循环退出。该错误发生在 doSomethingImportant 返回之后但在调用其中一个委托方法之前。EXC_BAD_ACCESS 错误发生在调用 NSRunLoop 时。这是堆栈跟踪的一部分:
#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
...
现在,如果我忽略在 doSomethingImportant 中设置自动释放池,我可以完全防止错误发生,并且包装的 API 似乎可以同步工作。但是,如果我要这样做,那么控制台中会打印以下内容:
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)
上面的这些消息是由 Connection 类实例中没有释放的东西引起的吗?我正在创建一个 NSDate 但不是需要发布的实例。与 NSTimer 相同。
我试图通过设置 NSAutoreleasePool 来做正确的事情,但看起来我做错了什么。但是,我不知道那可能是什么。非常感谢任何帮助!
富有的