块代替performSelector:withObject:afterDelay:
我经常想在未来几微秒执行一些代码。 现在,我解决这个问题:
- (void)someMethod { // some code }
和这个:
[self performSelector:@selector(someMethod) withObject:nil afterDelay:0.1];
它有效,但我必须每次创build一个新的方法。 是否可以使用块代替这个? 基本上我正在寻找一种方法,如:
[self performBlock:^{ // some code } afterDelay:0.1];
这对我来说真的很有用。
有没有内置的方式来做到这一点,但通过一个类别添加也不错:
@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的基本实施。
这是一个基于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专家,我对这个解决scheme感兴趣。
另一种方式(也许是由于许多原因做这个最糟糕的方式)是:
[UIView animateWithDuration:0.0 delay:5.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{ } completion:^(BOOL finished) { //do stuff here }];
如果您特别需要更长的延迟,上述解决scheme工作得很好。 我已经使用@尼克的方法取得了巨大的成功。
但是,如果您只是希望您的代码块在主循环的下一次迭代期间运行,则可以使用以下代码进一步修剪:
[[NSOperationQueue mainQueue] addOperationWithBlock:aBlock];
这类似于使用performSelector:with afterDelay为0.0f
我使用了类似的代码:
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... });
这里有一个很好的完整的类别来处理这种情况: