performSelector:withObject:afterDelay: 不在模态视图控制器上工作

Posted

技术标签:

【中文标题】performSelector:withObject:afterDelay: 不在模态视图控制器上工作【英文标题】:performSelector:withObject:afterDelay: not working on modal view controller 【发布时间】:2012-06-29 11:10:05 【问题描述】:

我有一个模态视图控制器,它会检查 Internet 上的服务,然后在完成后自行关闭。笔尖包含一个活动指示器和一个标签,用于通知用户正在发生的事情。

更新完成后,标签变为“更新完成”,然后关闭视图控制器。但是,我希望它将关闭延迟几秒钟,让用户有机会在文本消失之前看到它。所以我这样做了:

#pragma mark - AssetLoaderServiceDelegate

- (void)assetLoaderServiceDidFinishLoading:(AssetLoaderService *)service

    [self.spinner stopAnimating];
    self.infoLabel.text = @"Update complete";
    [self performSelector:@selector(dismissUpdater) withObject:nil afterDelay:2.0];


- (void)dismissUpdater

    [self dismissModalViewControllerAnimated:YES];

但由于某种原因,选择器永远不会被调用。我也试过在NSRunLoopCommonModes模式下运行它,但这也不起作用。

我一定是做错了什么,但我看不到什么......

编辑:委托回调实际上发生在NSOperationQueue 中,这可能意味着它在将消息发送回视图控制器时不在同一个线程上?所以我尝试了

[self performSelector:@selector(downloadQueueComplete) withObject:nil afterDelay:0.0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];

紧随其后

- (void)downloadQueueComplete

    [delegate assetLoaderServiceDidFinishLoading:self];

但是 performSelector 在这里似乎也不起作用。

【问题讨论】:

dismissUpdater 是否没有被调用,或者dismissModalViewControllerAnimated 方法不起作用? 你的意思是:1.assetLoaderServiceDidFinishLoading被调用; 2. 你的模态视图总是在那里? @rishi - 我的意思是没有调用dismissUpdater。 @sergio - 是的,如果我将dismissModalViewControllerAnimated: 方法移回assetLoaderServiceDidFinishLoading:,它会很好地解散。没有触发的是performSelector 【参考方案1】:

根据您对线程问题的建议,您会尝试:

[self performSelectorOnMainThread:@selector(downloadQueueComplete) withObject:nil waitUntilDone:YES]];

【讨论】:

是的,同时得到了相同的答案,谢谢!我似乎不需要NSRunLoopCommonModes 位,但除此之外,问题解决了。干杯:) 那是真正的同步性...感谢您接受我的回答,实际上您自己在那里... 这是公平的——我向你们寻求帮助;)【参考方案2】:

排序!在 AssetLoaderService 中,我不得不在主线程上执行选择器:

 [self performSelectorOnMainThread:@selector(downloadQueueComplete) withObject:nil waitUntilDone:YES];

之后,以下所有调用都在正确的线程上。 :)

【讨论】:

以上是关于performSelector:withObject:afterDelay: 不在模态视图控制器上工作的主要内容,如果未能解决你的问题,请参考以下文章