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
Alamofire:How to Handle Errors Globally
Install .Ipa to iPad with or Without Itunes
Find Where Object Is Retained with Arc
The Paper Folding/Unfolding Effect in Twitter for iPad
What Is Nsmanagedobjectcontext's Performblock: Used For
Iphone: Can a Dev Other Than Team Agent Build an App for Distribution
Get Uiscrollview to Scroll to the Top
"Rctbundleurlprovider.H" File Not Found - Appdelegate.M
Cabasicanimation Does Not Animate Correctly When I Update Model Layer
How to Change the Image Displayed in a Uiimageview Programmatically
How to Change Font of Uibutton with Swift
How to Deselect a Selected Uitableview Cell
Launch a Local Notification at a Specific Time in iOS
How to Ask User for Camera Access After They Have Already Denied It on iOS
How to Distribute iOS Applications Outside App Store