2012-09-19 54 views
0

我有一個應用程序爲網絡消息創建後臺線程。除非連接的服務器關閉連接,否則應用程序幾乎完美地工作。我不確定爲什麼發生這種情況,但任何建議非常感謝。我已經包含了可以遵循該問題的代碼片段。如果有些東西模糊或需要更多細節,請告訴我。後臺線程上的iOS網絡導致應用程序掛起

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode { 
switch(eventCode) { 
    case NSStreamEventErrorOccurred: 
     { 
      NSLog(@"NSStreamEventErrorOccurred"); 

      [self Disconnect:self]; 
     } 
    } 
} 

- (void)Disconnect:(id)sender { 
    [self performSelector:@selector(closeThread) onThread:[[self class]networkThread] withObject:nil waitUntilDone:YES]; 

    [outputStream close]; 
    [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [outputStream release]; 
    outputStream = nil; 
} 

+ (NSThread*)networkThread 
{ 
    // networkThread needs to be static otherwise I get an error about a missing block type specifier 
    static NSThread* networkThread = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     networkThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkThreadMain:) object:nil]; 

     [networkThread start]; 
    }); 

    return networkThread; 
} 

掛斷發生在return networkThread行上。執行該行後,應用程序似乎掛起並凍結,我無法理解爲什麼。

在此先感謝。

編輯

下面是對CloseThread代碼爲有志

- (void)closeThread 
{ 
    /*if(!inputStream) 
     return; 

    [inputStream close]; 
    [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; 
    [inputStream release]; 
    inputStream = nil;*/ 
} 
+0

你還沒有包含'-closeThread'的實現,我懷疑是你的實際問題。如果你只是退出線程,很可能你的'waitUntilDone:YES'永遠不會被通知它已經完成並且死鎖。 –

+0

我沒有添加該方法的原因是因爲我的斷點永遠不會被擊中。爲了確認它,我註釋了裏面的所有內容,以便該函數爲空。如果我手動決定在iPad GUI上斷開連接,代碼工作正常。 – Seb

+0

你在那個線程上運行runloop嗎? 'performSelector:onThread:...'要求目標線程有一個關聯的處理消息的runloop。 –

回答

1

我建議改變片段:

[自performSelector:@selector(closeThread)onThread:[ self class] networkThread] withObject:nil waitUntilDone:YES];

到:

[自performSelector:@selector(closeThread)onThread:[[自類] networkThread] withObject:無waitUntilDone:NO];

也就是說,不要等待。

+0

看起來像這個工作。我想等到我完成的主要原因是因爲我不想確保我的物體在移動前被移除並設置爲零。 – Seb

+0

實現這種同步的方式(如果您真的需要它)發送消息,不要做任何其他事情。在最終獲取消息的對象中,執行所需操作,最後使用另一個performSelectorOnMainThread或使用塊來重新開始工作。 –

相關問題