2012-09-19 56 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或使用块来重新开始工作。 –

相关问题