Blocks instead of performSelector: withObject: afterDelay:

I often want to execute code in a few microseconds in the future. Now I solve it like this:

- (void)someMethod { // some code } 

And this:

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

This works, but I have to create a new method every time. Can blocks be used instead? I'm basically looking for a way like:

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

That would be very helpful for me.

+85
ios objective-c iphone cocoa-touch objective-c-blocks
24 Oct '10 at 3:20
source share
6 answers

There is no built-in way to do this, but it is not so difficult to add through the 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 Mike Ash for a basic implementation.

+103
Oct 24 2018-10-10T00:
source share

Here is a simple GCD based method that I use:

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

I am not a GCD expert, and I would be interested to receive comments on this decision.

+39
Jan 20 '11 at 16:01
source share

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

 [UIView animateWithDuration:0.0 delay:5.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{ } completion:^(BOOL finished) { //do stuff here }]; 
+21
Nov 26 '11 at 23:19
source share

If you need a longer delay, the solutions above work very well. I used the @nick approach with great success.

However, if you just want your block to work during the next iteration of the main loop, you can further trim it as follows:

 [[NSOperationQueue mainQueue] addOperationWithBlock:aBlock]; 

This is akin to using the performSelector function: with afterDelay 0.0f

+15
Jul 23 2018-11-11T00:
source share

I used the same code:

 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... }); 
+11
Sep 11 '13 at 12:19
source share

Here is a good, complete category that handles this situation here:

https://gist.github.com/955123

+1
Aug 23 '12 at 19:25
source share



All Articles