Objective c 启用ARC的线程化Obj-C代码——为什么会这样?

Objective c 启用ARC的线程化Obj-C代码——为什么会这样?,objective-c,automatic-ref-counting,Objective C,Automatic Ref Counting,我需要一个额外的线程在后台侦听来自套接字的请求 代码被放入一个单例类中;它将在NSApplicationMain()之前的main.m中调用,如下所示: [[SKSocketThread getSingleton] runThread]; runThread的定义如下: - (void) runThread { [NSThread detachNewThreadSelector:@selector(socketThreadMainLoop:)

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

代码被放入一个单例类中;它将在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的调用,并且成功了


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

你应该用
@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?
}
}
阅读更多:

objc\u autoreleasenool
上设置断点并发布回溯。在所有不运行循环的线程中都需要@autoreleasepool{…},包括主线程(在main.m中,如果不调用NSApplicationMain())

一些额外的反馈;将方法命名为
getSingleton
表示您对iOS开发是新手(不要命名方法
get*
任何东西)。你在
循环中使用
睡眠
,而
循环表明你对整个网络也有点陌生

此外,在调用
NSApplicationMain()
之前旋转线程是完全错误的;你应该在应用程序启动的正常部分中进行网络goop。。。见下文

你真的不想使用带睡眠的手动while()循环进行联网。在移动设备上,轮询是一种糟糕的模式;它需要电池,而睡眠只会让事情失去反应


使用适当的运行循环和/或分派源和/或CFStream API和/或NSFileHandles。

它不起作用。相反,它将重复以下错误消息两次:
objc[64204]:NSLock类的对象0x100118a00在没有池的情况下自动释放-只是泄漏-在objc_autoreleasenool()上中断以调试objc[64204]:SKSocketThread类的对象0x100108c20在没有池的情况下自动释放-只是泄漏-在objc_autoreleasenool()上中断调试
我想知道这是否是因为我在线程中使用了
self
quitLock
。哈?他使用的是ARC,而不是GC。因此,任何辅助线程(不直接使用运行循环)都非常需要@autoreleasepool{}。我将尝试使用GCDAsyncSocket——这似乎很有希望。我查看了回溯,发现在init中设置quitLock属性后,当我尝试获取quitLock属性时调用了objc_autoreleasenool,该属性由getSingleton调用(我现在将其重命名为“sharedInstance”)。甚至在我调用runThread启动线程之前。。。