I'm trying to create a method with an argument in objective-c, the argument is an amount of seconds before the actual method starts.
I'm trying to avoid using the [self performSelector:(SEL) withObject:(id) afterDelay:(NSTimeInterval)]; because having the delay within my method would actually save me a lot of coding as I am planning to add other arguments to this method.
Example of the method:
-(void) startMethodAfterArgumentDelay: (NSTimeInterval *)delay{
NSLog(#"perform action after argument delay");
}
and how to call it:
[self startMethodAfterArgumentDelay:3.0f];
Any help would be greatly appreciated!
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");
});
}
You can use BlocksKit and then write code like that:
[self bk_performBlock:^(id obj) {
//code
} afterDelay:delay];
Just feed delay to dispatch_after.
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
// do whatever
});
Related
I am using tableview and I want to call a method after some time duration.This method return a array and reload the tableview.I want within this time duration UI doesn't stuck.
Best to use Grand Central Dispatch (GCD). If you call dispatch_after(), you can run a block of code whenever you want.
// Run this code after 1 second.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self someMethod];
});
I have an iOS Xcode question I'm hoping someone can help me out with. I have a simple action button that invokes a series of methods to run, however these methods all write to a stream and retrieve the input that comes in return, so I'm having a hard time reading the stream and extracting the information.
I think this is because its all happening too fast. I would like it where i press the button and method one runs, waits half a second (for example), then method two, then method three, etc... can someone show me a simple code to do so please?
Thanks in advance, example below:
Chuck
- (IBAction)updateStatsButton:(id)sender {
[self method1];
[self method2];
[self method3];
self.label1.text = result from method 1;
self.label2.text = result from method 2;
self.label3.text = result from method 3;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self method1];
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self method2];
});
[self performSelector:#selector(method1) withObject:nil afterDelay:2];
I got stuck in a problem. I'm trying to run a timer in a method which itself is in background resulting my timer is not initiating. I got to know some where that timer can't be initialized in background so is there any way to do this?
You can perform the operation on main thread.
[self performSelectorOnMainThread:#selector(initTimer) withObject:nil waitUntilDone:NO];
and then
- (void)initTimer {
// Init your timer here.
}
You can try Background Fetch in ios7 to run code on background
Try this :
// provide value as required. Time here is 3 sec
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 3.0 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// do your task
});
As pointed out by #Bryan Chen, you can schedule a method to be run on the current thread using the following code:
dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC);
dispatch_after(when, dispatch_get_current_queue(), ^(void) {
[self myTimedMethod];
});
You cannot use NSTimer in a background thread unless you are maintaining a run loop on that thread.
I want to call a method after certain time.
This is just an example.
- (void)myMethod:(int)value1 setValue2:(CGPoint)value2{
//Do Something with values
}
At first I thought
[self scheduleOnce:#selector(myMethod:setValue2:) delay:timeToWait];
but I can't pass the arguments when using selector, so Im asking you guys for an alternative...What could I do?
Thanks for your time guys and have a great day!
You can try GCD's dispatch_after. For instance:
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self myMethod:someValue setValue2: someValue2];
});
You could put your arguments into an NSDictionary and pass that as the object parameter to - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay
I have a need to delay for a certain amount of time and yet allow other things on the same runloop to keep running. I have been using the following code to do this:
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
This seems to do exactly what I want, except that sometimes the function returns immediately without waiting the desired time (1 second).
Can anyone let me know what could cause this? And what is the proper way to wait while allowing the run loop to run?
NOTE: I want to delay in a manner similar to sleep(), such that after the delay I am back in the same execution stream as before.
You should use GCD and dispatch_after for that. It is much more recent and efficient (and thread-safe and all), and very easy to use.
There is even a code snippet embedded in Xcode, so that if you start typing dispatch_after it will suggest the snippet and if you validate it will write the prepared 2-3 lines for you in your code :)
int64_t 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#>
});
Use an NSTimer to fire off a call to some method after a certain delay.
Have you tried performSelector:withObject:afterDelay:?
From the Apple documentation
Invokes a method of the receiver on the current thread using the default mode after a delay.
I had a similar issue and this is my solution. Hope it works for others as well.
__block bool dispatched = false;
while ( put your loop condition here )
{
if (dispatched)
{
// We want to relinquish control if we are already dispatched on this iteration.
[ [ NSRunLoop currentRunLoop ] runMode: NSDefaultRunLoopMode beforeDate:[ NSDate date ] ];
continue;
}
// mark that a dispatch is being scheduled
dispatched = true;
int64_t delayInNanoSeconds = (int64_t) (0.1 * (float) NSEC_PER_SEC);
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, delayInNanoSeconds);
dispatch_after(delayTime, dispatch_get_main_queue(), ^() {
// Do your loop stuff here
// and now ready for the next dispatch
dispatched = false;
} );
} // end of while