cancelPreviousPerformRequestsWithTarget不取消未完成的performSelector:withDelay

Gru*_*kes 11 ios

我正在使用a UIWebView并且不希望导航栏出现,除非用户点击屏幕上不是链接的任何地方.所以我有这段代码在延迟后显示导航栏:

- (void)handleTapGesture:(UITapGestureRecognizer *)sender  
{      
.... 
[self performSelector:@selector(showNavigationBar) withObject:self afterDelay:0.2]; 
}
Run Code Online (Sandbox Code Playgroud)

调用showNavigationBartap处理程序时我没有立即调用,因为用户可能已经点击了链接,在这种情况下,之前 调用了轻击手UIWebView shouldStartLoadWithRequest,所以如果我隐藏导航栏,shouldStartLoadWithRequest它会瞬间闪现在屏幕上.所以我把它设置为在延迟之后显示,这给了下面代码在其中执行的时间shouldStartLoadWithRequest(如果用户没有点击链接shouldStartLoadWithRequest没有被调用并且显示导航栏,那么在那种情况下应该如此) ).

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType  
{ 
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showNavigationBar) object:nil];
...
Run Code Online (Sandbox Code Playgroud)

但是这不起作用,我已经将延迟时间增加到几秒钟并且可以确认cancelPreviousPerformRequestWithTarget在显示导航栏之前调用,但是当指定的时间过去时,显示条形图.cancelPreviousPerformRequestWithTarget没有效果.

有谁知道它为什么不起作用?

Dav*_*ton 15

您的演出与您的取消不符.在演出中,你将自己作为对象传递:

[self performSelector:@selector(showNavigationBar) withObject:self afterDelay:0.2]; 
Run Code Online (Sandbox Code Playgroud)

在取消中,你传递的是nil作为对象:

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showNavigationBar) object:nil];
Run Code Online (Sandbox Code Playgroud)

它们不匹配,因此不应取消延迟执行.

  • 我只是这样做没有运气.所以我试图删除所有请求:[NSObject cancelPreviousPerformRequestsWithTarget:self]; 现在它就像一个魅力. (2认同)

Vin*_*ier 12

在该方法的文档+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument有这样一句话:

此方法仅在当前运行循环中删除执行请求,而不是所有运行循环.

如果我正确地解释它,则意味着您需要在启动它的同一个运行循环中取消操作.这显然不是你想要做的.

解决这个问题的方法是拥有一个标志,showNavigationBar必须检查它是否应该继续或中止.