performSelector:OnThread:waitUntilDone 一直不执行选择器 [英] performSelector:OnThread:waitUntilDone not executing the selector all the time

查看:158
本文介绍了performSelector:OnThread:waitUntilDone 一直不执行选择器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an app where the network activity is done in its separate thread (and the network thread continuously gets data from the server and updates the display - the display calls are made back on the main thread). When the user logs out, the main thread calls a disconnect method on the network thread as follows:

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

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

This selector gets called most of the time and everything works fine. However, there are times (maybe 2 out of ten times) that this call never returns (in other words the selector never gets executed) and the thread and the app just hang. Anyone know why performSelector is behaving erratically?

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

Please note that I need to wait until the call gets executed, that's why waitUntilDone is YES, so changing that to NO is not an option for me. Also the network thread has its run loop running (I explicitly start it when the thread is created).

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

Please also note that due to the continuous nature of the data transfer, I need to explicitly use NSThreads and not GCD or Operations queues.

推荐答案

如果:

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

  • it is attempting to perform a selector on the same thread the method was called from

执行选择器的调用是针对一个线程,在该线程中进行了触发执行选择器的同步调用

the call to perform the selector is to a thread from which a synchronous call was made that triggered the perform selector

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

When your program is hung, have a look at the backtraces of all threads.

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

Note that when implementing any kind of networking concurrency, it is generally really bad to have synchronous calls from the networking code into the UI layers or onto other threads. The networking thread needs to be very responsive and, thus, just like blocking the main thread is bad, anything that can block the networking thread is a bad, too.

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

Note also that some APIs with callbacks don't necessarily guarantee which thread the callback will be delivered on. This can lead to intermittent lockups, as described.

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

Finally, don't do any active polling. Your networking thread should be fully quiescent unless some event arrives. Any kind of looped polling is bad for battery life and responsiveness.

这篇关于performSelector:OnThread:waitUntilDone 一直不执行选择器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆