我经常想在将来几微秒内执行一些代码。现在,我这样解决:
- (void)someMethod
{
// some code
}
而且:
[self performSelector:@selector(someMethod) withObject:nil afterDelay:0.1];
它有效,但我每次都要创建一个新方法。是否可以使用块而不是这个?基本上我正在寻找一种方法:
[self performBlock:^{
// some code
} afterDelay:0.1];
这对我来说真的很有用。
答案 0 :(得分:106)
没有内置的方法可以做到这一点,但通过类别添加并不是太糟糕:
@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
归功于Mike Ash的基本实施。
答案 1 :(得分:41)
这是一个基于GCD的简单技术,我正在使用:
void RunBlockAfterDelay(NSTimeInterval delay, void (^block)(void))
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*delay),
dispatch_get_current_queue(), block);
}
我不是GCD专家,我对此解决方案的评论感兴趣。
答案 2 :(得分:22)
另一种方式(也许是出于多种原因最糟糕的做法)是:
[UIView animateWithDuration:0.0 delay:5.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
} completion:^(BOOL finished) {
//do stuff here
}];
答案 3 :(得分:16)
如果你特别需要更长的延迟,上面的解决方案就可以了。我用@ nick的方法取得了巨大的成功。
但是,如果您只想在主循环的下一次迭代期间运行块,则可以使用以下内容进一步修剪它:
[[NSOperationQueue mainQueue] addOperationWithBlock:aBlock];
这类似于使用performSelector:afterDelay为0.0f
答案 4 :(得分:11)
我使用了类似的代码:
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...
});
答案 5 :(得分:1)
这里有一个很好的完整类别来处理这种情况: