ios 块而不是 performSelector:withObject:afterDelay:

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4007023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:58:00  来源:igfitidea点击:

Blocks instead of performSelector:withObject:afterDelay:

iphoneobjective-ccocoa-touchiosobjective-c-blocks

提问by Rits

I often want to execute some code a few microseconds in the future. Right now, I solve it like this:

我经常想在未来几微秒内执行一些代码。现在,我是这样解决的:

- (void)someMethod
{
    // some code
}

And this:

和这个:

[self performSelector:@selector(someMethod) withObject:nil afterDelay:0.1];

It works, but I have to create a new method every time. Is it possible to use blocks instead of this? Basically I'm looking for a method like:

它有效,但我每次都必须创建一个新方法。是否可以使用块来代替这个?基本上我正在寻找一种方法,如:

[self performBlock:^{
    // some code
} afterDelay:0.1];

That would be really useful to me.

那对我真的很有用。

回答by John Calsbeek

There's no built-in way to do that, but it's not too bad to add via a category:

没有内置的方法可以做到这一点,但通过类别添加还不错:

@implementation NSObject (PerformBlockAfterDelay)

- (void)performBlock:(void (^)(void))block 
          afterDelay:(NSTimeInterval)delay 
{
    block = [[block copy] autorelease];
    [self performSelector:@selector(fireBlockAfterDelay:) 
               withObject:block 
               afterDelay:delay];
}

- (void)fireBlockAfterDelay:(void (^)(void))block {
    block();
}

@end

Credit to Mike Ashfor the basic implementation.

归功于Mike Ash的基本实现。

回答by Nick Moore

Here's a simple technique, based on GCD, that I'm using:

这是我正在使用的基于 GCD 的简单技术:

void RunBlockAfterDelay(NSTimeInterval delay, void (^block)(void))
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*delay),
      dispatch_get_current_queue(), block);
}

I'm not a GCD expert, and I'd be interested in comments on this solution.

我不是 GCD 专家,我对对此解决方案的评论很感兴趣。

回答by ninjaneer

Another way (perhaps the worst way to do this for many reasons) is:

另一种方法(可能出于多种原因是最糟糕的方法)是:

[UIView animateWithDuration:0.0 delay:5.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
} completion:^(BOOL finished) {
    //do stuff here
}];

回答by Greg Combs

If you specifically need a longer delay, the solutions above work just fine. I've used @nick's approach with great success.

如果您特别需要更长的延迟,上述解决方案就可以正常工作。我已经成功地使用了@nick 的方法。

However, if you just want your block to run during the next iteration of the main loop, you can trim it down even further with just the following:

但是,如果您只想让您的块在主循环的下一次迭代中运行,您可以使用以下命令进一步减少它:

[[NSOperationQueue mainQueue] addOperationWithBlock:aBlock];

This is akin to using performSelector: with afterDelay of 0.0f

这类似于使用 performSelector: with afterDelay 0.0f

回答by Despotovic

I used similar code like this:

我使用了类似的代码:

double delayInSeconds = 0.2f;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
      //whatever you wanted to do here...  
    });

回答by Duane Fields

There's a nice, complete category that handles this situation here:

这里有一个很好的完整类别可以处理这种情况:

https://gist.github.com/955123

https://gist.github.com/955123