延迟为 0 的“performSelector:withObject:afterDelay:”与仅调用选择器有啥区别?
Posted
技术标签:
【中文标题】延迟为 0 的“performSelector:withObject:afterDelay:”与仅调用选择器有啥区别?【英文标题】:What's the difference between "performSelector:withObject:afterDelay:" where delay is 0, and just calling the selector?延迟为 0 的“performSelector:withObject:afterDelay:”与仅调用选择器有什么区别? 【发布时间】:2012-10-19 03:38:01 【问题描述】:我正在开发一个使用第三方 SDK 的 iPad 项目,并且一直在阅读 SDK 代码以了解它和 Objective-c。我在异步回调中遇到了以下行:
[self performSelector:@selector(doSomething) withObject:nil afterDelay:0];
我已经阅读了该选择器上的the documentation。相关行似乎如下:
指定延迟为 0 并不一定会导致选择器立即执行。选择器仍在线程的运行循环中排队并尽快执行。
我无法确定为什么要写[self performSelector:@selector(doSomething) withObject:nil afterDelay:0]
,而不是仅仅写[self doSomething]
。在我看来,零延迟意味着应该立即拨打电话。显然我遗漏了一些东西,框架作者不太可能随机选择这种方法。其他 *** 答案也没有说明这一点。使用“performSelector”选择器是因为 doSomething 选择器本身是异步的,并且调用是在异步回调中进行的吗?
我确实找到了 another link 提出以下建议:
有趣的是,使用 performSelector 和 afterDelay 也会让警告 [即,编译器警告] 消失:...
[self performSelector:aSelector withObject:nil afterDelay:0.0];
那么作者使用这段代码只是为了抑制编译器警告吗?如果是这种情况,那么最好按照this thread 中的建议通过clang push/pops 来抑制警告。
如果有人对作者为什么使用 ...afterDelay 方法有中肯的解释,我将不胜感激。谢谢。
2012 年 10 月 22 日编辑:我不认为 @rmaddy 在这里给出的唯一答案完全适用于我的情况,但它仍然是一个很好的答案,所以我会接受.我会密切关注这个问题,如果我发现任何新内容,我会回来。谢谢。 J.Z.
【问题讨论】:
你能指出我们的框架吗?它可能有助于提供上下文。 @drekka:是Salesforce ios SDK。问题是关于 /native/SalesforceSDK/SalesforceSDK/Classes/NativeApp/SFNativeRestAppDelegate.m 中的一行。 【参考方案1】:一种可能的用法,例如:
[self performSelector:@selector(doSomething) withObject:nil afterDelay:0];
是允许当前运行循环在调用 'doSomething' 之前完成。换句话说,当前调用堆栈可以在调用 'doSomething' 之前完成(当前方法返回)。这通常用于让 UI 有机会更新。
虽然没有更多上下文,但很难知道作者的真实意图,但这是一种常见的用法。
【讨论】:
正确,但要挑剔:不是调用堆栈;强调电流通过可能相当复杂的运行循环(去阅读关于 CFRunLoop 的所有阶段的文档)。一般来说,应该避免这种模式(尽管有时是必要的),因为它往往很脆弱,并且当一个 after-delay-0 触发另一个 after-delay-0 触发另一个 after-delay- 时会产生相当多的乐趣0等.... @rmaddy:我明白了。在这种情况下,它似乎不适用。该调用是在 OAuth 2.0 周期内的异步回调中进行的(OAuth 的内容与问题无关),因此“当前运行循环”的概念可能不适用。 @bbum 我在写“调用堆栈”时就知道这不是一个正确的术语。感谢您的澄清。以上是关于延迟为 0 的“performSelector:withObject:afterDelay:”与仅调用选择器有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章