Objective-C Delay Action with Blocks

Objective-C delay action with blocks

use dispatch_after:

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//code to be executed on the main queue after delay
[self doSometingWithObject:obj1 andAnotherObject:obj2];
});

Adding delay between execution of two following lines

You can use gcd to do this without having to create another method

// ObjC

NSTimeInterval delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
NSLog(@"Do some work");
});

// Swift

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
print("Do some work)
}

You should still ask yourself "do I really need to add a delay" as it can often complicate code and cause race conditions

Creating a method in objective-c with a delay argument

If you don't want to use any 3rd party libraries as the other answer suggested, this is easy enough to implement yourself using GCD's dispatch_after(). Just note that this method is a asynchronous, so your method will return immediately even though the contents of the block are delayed.

- (void)startMethodAfterArgumentDelay:(NSTimeInterval)delay
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"perform action after argument delay");
});
}

ALL UIButton's delay executing block

The problem turned out to be with the MapBox API(Not Recommended) in my project, removing this sped everything up. All code was fine, have gone back to performing selector and removed the gestures.

How to add a delay to a loop?

It will be more efficient to use an NSTimer.

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:numberOfSeconds
target:self
selector:@selector(methodToAddImages:)
userInfo:nil
repeats:YES];

This will essentially call methodToAddImages repeatedly with the specified time interval. To stop this method from being called, call [NSTimer invalidate] (bear in mind that an invalidated timer cannot be reused, and you will need to create a new timer object in case you want to repeat this process).

Inside methodToAddImages you should have code to go over the array and add the images.
You can use a counter variable to track the index.

Another option (my recommendation) is to have a mutable copy of this array and add lastObject as a subview and then remove it from the mutable copy of your array.

You can do this by first making a mutableCopy in reversed order as shown:

NSMutableArray* reversedImages = [[[images reverseObjectEnumerator] allObjects] mutableCopy];

Your methodToAddImages looks like:

- (void)methodToAddImages
{
if([reversedImages lastObject] == nil)
{
[timer invalidate];
return;
}

UIImageView *imageView = [[UIImageView alloc] initWithFrame:(CGRectMake(40, 40, 40, 40))];
imageView.image = [reversedImages lastObject];
[self.view addSubview:imageView];
[reversedImages removeObject:[reversedImages lastObject]];
}

I don't know if you're using ARC or Manual Retain Release, but this answer is written assuming ARC (based on the code in your question).

Objective C for loop delay

The for loop will dispatch one right after the other so they will essentially delay for the same time.

Instead set a different increasing delay for each:

double delayInSeconds = 0.0;
for(NSNumber* transaction in gainsArray)
{
delayInSeconds += 5.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
{
NSLog(@"Block");
[self performSelectorOnMainThread:@selector(private_addTransactionToBankroll:)
withObject:transaction
waitUntilDone:NO];

});
}

Objective-C delay a method in iOS 6 dispatch_get_current_queue deprecated

I think you should use dispatch_get_global_queue() instead. It should do about the same i think. If you are only interested in delaying the method and not running in another que you could just use dispatch_get_main_queue(). Just remember that you can't update user interface if you are not in the main que.

How can I delay a method call for 1 second?

performSelector:withObject:afterDelay:

Document Reference

Blocks instead of performSelector:withObject:afterDelay:]

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 Ash for the basic implementation.



Related Topics



Leave a reply



Submit