0

我有一个应用程序,其中网络活动在其单独的线程中完成(并且网络线程不断从服务器获取数据并更新显示 - 显示调用在主线程上进行)。当用户注销时,主线程在网络线程上调用一个disconnect方法如下:

[self performSelector:@selector(disconnectWithErrorOnNetworkThread:) onThread:nThread withObject:e waitUntilDone:YES];

这个选择器大部分时间都会被调用,一切正常。但是,有时(可能十分之二)此调用永远不会返回(换句话说,选择器永远不会被执行)并且线程和应用程序只是挂起。任何人都知道为什么 performSelector 行为不正常?

请注意,我需要等到调用被执行,这就是为什么 waitUntilDone 为 YES,所以将其更改为 NO 对我来说不是一个选项。网络线程也运行其运行循环(我在创建线程时显式启动它)。

另请注意,由于数据传输的连续性,我需要明确使用 NSThreads 而不是 GCD 或操作队列。

4

1 回答 1

3

如果出现以下情况,那将挂起:

  • 它试图在调用该方法的同一线程上执行选择器

  • 执行选择器的调用是对触发执行选择器的同步调用的线程

当您的程序挂起时,请查看所有线程的回溯。

请注意,在实现任何类型的网络并发时,将网络代码同步调用到 UI 层或其他线程通常是非常糟糕的。网络线程需要非常敏感,因此,就像阻塞主线程是不好的一样,任何可以阻塞网络线程的东西也是不好的。

另请注意,某些带有回调的 API 不一定保证回调将被传递到哪个线程。如前所述,这可能导致间歇性锁定。

最后,不要进行任何主动轮询。除非某些事件到达,否则您的网络线程应该完全静止。任何类型的循环轮询都不利于电池寿命和响应能力。

于 2012-11-05T21:34:47.293 回答