2012-10-19 25 views
0

我需要一个额外的线程在后台侦听来自套接字的请求。启用ARC的Threaded Obj-C代码 - 为什么它以这种方式工作?

该代码被放入单例类;它将在main.m文件被称为NSApplicationMain()这样的前:

而且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. 

我做了一些谷歌搜索,试图runThread和socketThreadMainLoop将代码与@autoreleasepool,但错误依然存在。最后,我用main.m将调用包装到runThread中,并且工作正常!

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

回答

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

+0

它不起作用。相反,它会重复两次以下错误信息: ''objc [64204]:NSLock类的对象0x100118a00自动释放,没有就位 - 只是泄漏 - 在objc_autoreleaseNoPool()上进行调试以调试 objc [64204]:对象0x100108c20 class SKSocketThread autoreleased没有池 - 只是泄漏 - 打破objc_autoreleaseNoPool()调试 – wecing

+0

我不知道是否因为我在线程中使用'self'和'quitLock'。 – wecing

+0

咦?他正在使用ARC,而不是GC。因此,任何辅助线程(不直接使用运行循环)都非常需要@autoreleasepool {}。 – bbum

0

设置一个断点上objc_autoreleaseNoPool和发布回溯。您需要在所有线程中使用@autoreleasepool {...},这些线程不会运行循环,包括主线程(如果您未调用NSApplicationMain(),则在main.m中)。

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

此外,在调用NSApplicationMain()之前旋转线程完全是错误的做法;您应该将网络goop作为应用程序启动的正常组成部分......请参阅下文。

你真的真的真的不想做使用手卷while()循环睡眠联网。轮询在移动设备上是非常糟糕的模式;这是电池饥饿,sleep只是让事情没有反应。

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

+0

谢谢你的回复,真的。我会尝试GCDAsyncSocket - 它看起来很有希望。 – wecing

+0

我看了一下回溯,发现objc_autoreleaseNoPool在我试图在getSingleton(我现在将其重命名为“sharedInstance”)的init中设置它之后立即获取quitLock属性时调用。甚至在我调用runThread之前启动线程...... – wecing

相关问题