启用ARC的螺纹Obj-C代码 - 为什么它以这种方式工作?

时间:2012-10-19 20:33:35

标签: objective-c automatic-ref-counting

我需要在后台使用额外的线程来侦听来自套接字的请求。

将代码放入单例类中;它将在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调用了runThread,这很有效!

我不知道为什么它只能以这种方式运作......

2 个答案:

答案 0 :(得分: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 Class Reference

答案 1 :(得分:0)

objc_autoreleaseNoPool上设置断点并发布回溯。在我们运行循环的所有线程中都需要一个@autoreleasepool {...},包括主线程(如果你没有调用NSApplicationMain(),则在你的main.m中)。

一些额外的反馈;您命名方法getSingleton表示您不熟悉iOS开发(不要将方法命名为get*)。你在sleep循环中使用while表示你对整个网络事物也有点新意。

另外,在调用NSApplicationMain()之前启动一个线程是完全错误的事情;你应该做网络goop作为应用程序启动的正常部分...见下文。

你真的真的 真的不希望使用带睡眠的手动while()循环进行网络连接。轮询是移动设备上糟糕的模式;它耗费电量,而sleep只会让事情变得无法应对。

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