0

我需要一个额外的后台线程来监听来自套接字的请求。

代码放入单例类;它将在 NSApplicationMain() 之前的 main.m 中调用,如下所示:

 [[SKSocketThread getSingleton] runThread];

runThread 定义如下:

- (void) runThread {
    [NSThread detachNewThreadSelector:@selector(socketThreadMainLoop:)
                             toTarget:self
                           withObject:[self quitLock]];
}

- (void) socketThreadMainLoop:(id)param {
    NSLock *lock = (NSLock *)param;
    while (![lock tryLock]) {
        NSLog(@"Yay! We are in socketThreadMainLoop now!");
        [NSThread sleepForTimeInterval:2];
    }
    NSLog(@"Terminating the socket thread...");
    [lock unlock]; // is it really necessary?
}

它编译成功,没有警告,但会在运行时抛出错误:

autoreleased with no pool in place.

我做了一些谷歌搜索,尝试使用@autoreleasepool 在runThread 和socketThreadMainLoop 中打包代码,但错误仍然存​​在。最后,我在 main.m 中封装了对 runThread 的调用,并且成功了!

我不知道为什么它只能这样工作......

4

2 回答 2

0

你应该用@autoreleasepool块包装你的代码。

...
- (void) socketThreadMainLoop:(id)param {
@autoreleasepool
{    
    NSLock *lock = (NSLock *)param;
    while (![lock tryLock]) {
        NSLog(@"Yay! We are in socketThreadMainLoop now!");
        [NSThread sleepForTimeInterval:2];
    }
    NSLog(@"Terminating the socket thread...");
    [lock unlock]; // is it really necessary?
}
}

阅读更多: NSAutoreleasePool 类参考

于 2012-10-19T20:44:05.150 回答
0

设置断点objc_autoreleaseNoPool并发布回溯。您需要在所有不运行循环的线程中使用@autoreleasepool{...},包括主线程(在您的 main.m 中,如果您没有调用 NSApplicationMain())。

一些额外的反馈;您命名该方法getSingleton表明您是 iOS 开发的新手(不要命名get*任何方法)。您sleepwhile循环中使用表明您对整个网络事物也有点陌生。

此外,在调用之前启动线程NSApplicationMain()是完全错误的事情。您应该将网络连接作为应用程序启动的正常部分...见下文。

你真的真的 真的不想使用带睡眠的手动 while() 循环来进行网络连接。轮询在移动设备上是一种糟糕的模式。它很耗电,sleep只会让事情变得没有反应。

使用正确的运行循环和/或调度源和/或 CFStream API 和/或 NSFileHandles。

于 2012-10-19T20:58:24.827 回答