2012-10-19 24 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

相關問題