我有一个应用程序,其网络活动在其单独的线程中完成(并且网络线程不断从服务器获取数据并更新显示 - 显示调用在主线程上进行)。当用户注销时,主线程在网络线程上调用disconnect方法,如下所示:
[self performSelector:@selector(disconnectWithErrorOnNetworkThread:) onThread:nThread withObject:e waitUntilDone:YES];
大部分时间都会调用此选择器,一切正常。但是,有时候(可能是十分之二),这个调用永远不会返回(换句话说,选择器永远不会被执行),线程和应用程序就会挂起。有人知道为什么performSelector行为不正常吗?
请注意,我需要等到调用执行完毕,这就是为什么waitUntilDone为YES,所以将其更改为NO对我来说不是一个选项。网络线程也运行它的运行循环(我在创建线程时显式启动它。)
请注意,由于数据传输的连续性,我需要明确使用NSThreads而不是GCD或操作队列。
答案 0 :(得分:3)
如果:
那就会挂起它试图在调用方法的同一个线程上执行选择器
执行选择器的调用是指从中进行同步调用的线程,该线程触发了执行选择器
当您的程序挂起时,请查看所有线程的回溯。
请注意,在实现任何类型的网络并发时,从网络代码到UI层或其他线程的同步调用通常非常糟糕。网络线程需要非常敏感,因此就像阻塞主线程一样糟糕,任何可以阻止网络线程的东西都是坏事。
另请注意,某些带回调的API不一定能保证回调将在哪个线程上传递。如上所述,这可能导致间歇性锁定。
最后,不要进行任何有效的轮询。除非某些事件到来,否则您的网络线程应该完全静止。任何类型的循环轮询都不利于电池寿命和响应能力。