specifying #selector for method on another object? - iphone

Quick question, is there a way to specify a #selector that is a method on another object. Currently I have fudged a solution by using a local method to call the remote method, but it feels clunky.
[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:#selector(timerLocation) userInfo:nil repeats:YES]];
.
- (void)timerLocation {
[[self dataModel] startUpdatingLocation];
}

That's what the target portion of the NSTimer scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: method is for. (i.e.: You specify the object you want to call as the target and the name of the object's method as the selector.)

[NSTimer scheduledTimerWithTimeInterval:10 target:someOtherObject selector:#selector(timerLocation) userInfo:nil repeats:YES];

Related

How to call parameterized method with more than 2 parameters to the selector [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Arguments in #selector
How to call parameterized method with more than 2 parameters to the selector,
say for EX i have a method like this
-(void)GetTheData:(NSString *)str1 :(NSString *)str2
Now i need to call this method in the following timer inside the #selector.How can i call??
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:#selector(**HowCanICallHere**) userInfo:nil repeats:YES];
Pass NSDictionaryas a parameter to the target method
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:#"1",#"parameter1",#"2",#"parameter2", nil];
[ NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(myFunction:) userInfo: dictionary repeats:NO];
Further retrieving the parameters in the target function
-(void)myFunction:(NSTimer *)timer{
NSLog(#" dict : %#",timer.userInfo);
}
This way you may multiple parameters can be passed by adding more keyValue pairs in the NSDictionary
I'm not sure that you can. For the same reason "userInfo" option is given to us, to pass more than one parameter. You can easily implement that by creating a dictionary with two objects:
NSDictionary *dict = [NSDictionary dictionaryWithObjects:objArray andKeys:keyArray];
and pass that dictionary as userInfo object to the method:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:#selector(urTimerMethod:) userInfo:dict repeats:YES];
define the method as:
- (void)urTimerMethod:(NSTimer *)timer {
NSDictionary *dict = [timer userInfo];
}
You can use this:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:#selector(GetTheData::) userInfo:nil repeats:YES];
I know how to use it with a perform-selector, so maybe you could do it the following way:
-(void)GetTheData1:(NSString *)str1 GetTheData2:(NSString *)str2
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:#selector(mymethod) userInfo:nil repeats:YES];
- (void) mymethod {
[self performSelector:#selector(GetTheData1:GetTheData2:) withObject:str1 withObject:str2];
}

I want to invalidate all [self performSelector:#selector(showLyrics) withObject:nil afterDelay:2];

I am adding
[self performSelector:#selector(showLyrics) withObject:nil afterDelay:20];
but if user restart the song then the this selector should not get performed. So I just want to
know how I can cancel that. Because after 20 second it will get invoked but I don't want that, and reschedule
[self performSelector:#selector(showLyrics) withObject:nil afterDelay:20];
I'v so many
[self performSelector:#selector(showLyrics) withObject:nil afterDelay:2];
I want to cancel all those, which I've scheduled before.
[[NSRunLoop currentRunLoop] cancelPerformSelector:#selector(showLyrics)
target:self
argument:nil];
You can use NSTimer instead of performSelector:withObject:afterDelay:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:20 target:self selector:#selector(showLyrics) userInfo:nil repeats:NO];
To cancel:
[timer invalidate];
But you may want to invalidate before you start each time or keep timers in an array and iterate through them to cancel all of them.
Use an NSTimer and save a reference to it instead of performSelector. Afaik performSelector can't be cancelled. Edit: Apparently it can be cancelled, see omz's answer...
self.showLyricsTimer = [NSTimer scheduledTimerWithTimeInterval:20.0
target:self
selector:#selector(showLyrics)
userInfo:nil
repeats:NO];
To cancel the timer you use:
[self.showLyricsTimer invalidate];
But be careful to also invalidate the timer when your view disappears f.e. in the viewWillDisappear callback, since NSTimer retains it's target.
Cancels perform requests previously registered with performSelector:withObject:afterDelay:
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument
It seems this is what you are looking for or what you were looking for~~

Stopping a 'performSelector afterDelay' before it fires

I start a repeating NSTimer after a 4 second delay using the following code:
- (void)viewDidLoad {
[self performSelector:#selector(startTimer) withObject:self afterDelay:4];
}
- (void)startTimer {
NSTimer *mytimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(doSomething) userInfo:nil repeats:YES];
}
- (void)doSomething {
NSLog(#"What up!");
}
Problem is I may need to cancel startTimer from being called before the 4 seconds is up. Is there a way of doing this? I'd actually prefer to not use the performSelector in the first place (seems messy). If only NSTimer had something along the lines of this…
NSTimer *mytimer = [NSTimer
scheduledTimerWithTimeInterval:1.0
afterDelay:4.0 target:self
selector:#selector(doSomething)
userInfo:nil repeats:YES];
…then that would be perfect as I could just call the following:
[myTimer invalidate];
Any help or tips are much appreciated =)
P.S. I've found something called cancelPreviousPerformRequestsWithTarget in the NSObject class reference. Doesn't seem to be a method I can call from where this code runs however. If that's getting back on the right track your feedback is welcome!
Plz go through the SP post link
Stopping a performSelector: from being performed
[NSObject cancelPreviousPerformRequestsWithTarget:self
selector:#selector(sr)
object:nil];
The documentation for -performSelector:withObject:afterDelay: points you to the methods for canceling a queued perform request.
[myTimer invalidate] doesn't work?
Just keep a track of the object in your class, or in a centralized store for example.
If you do so, you could access your timer from everywhere you want, and invalidate it whenever it is needed
Use the NSTimer to fix issue.
self.autoTimer = [NSTimer timerWithTimeInterval:3.0 target:self
selector:#selector(connectionTimeout:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:autoTimer
forMode:NSDefaultRunLoopMode];
and call when you want to stop timer
[self.autoTimer invalidate];
self.autoTimer = nil;

Problem with NSTimer called inside my -parserDidEndDocument

I have a NSTimer object.
timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:#selector(timerAction) userInfo:nil repeats:YES];
[timer fire];
The method 'timerAction' repeats perfectly when call the timer from viewDidLoad method, but when I call the timer from parserDidEndDocument, the method 'timerAction' runs only once. Why is this?
you can try running the timer on the main thread.
Try this
create a new method that includes the code, to start timer, like :-
-(void)createTimer{
timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:#selector(timerAction) userInfo:nil repeats:YES];
[timer fire];
}
In Your parserDidEndDocument delegate, try this:
[self performSelectorOnMainThread:#selector(createTimer) withObject:[nil waitUntilDone:YES]

Nstimer with method that have variable

I have a method that have input variable and I need to schedule this method usingNSTimer
Unfortunately when I try to make the idea I got some error
My code is the following:
My method:
-(void)movelabel:(UILabel *)label {
}
I make my scheduling using the following:
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(movelabel:myLbabeName) userInfo:nil repeats:YES];
But, I got the following error:
error: expected ':' before ')' token
In other case (case of method without input variable i'm calling the timer like the following:
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(myMethodNameWithoutVariable) userInfo:nil repeats:YES];
Regards
The selector you give to scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: does not take arbitrary arguments. It should be either a selector without parameter or a selector with a single parameter of type (NSTimer *).
That means you can't directly call moveLabel: with your parameter myLbabeName.
You could use the userInfo dictionary with an intermediary method like this:
(timerRef is a NSTimer class variable)
timerRef = [NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:#selector(timerMovelabel:)
userInfo:[NSDictionary dictionaryWithObject:myLbabeName
forKey:#"name"]
repeats:YES];
and
- (void)timerMovelabel:(NSTimer *)timer {
[self movelabel:[[timer userInfo] objectForKey:#"name"]];
}
EDIT
If you want to stop the timer, keep a reference to it and call [timerRef invalidate]
You need to add ':' after the parameter, i.e.
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(movelabel:myLbabeName:) userInfo:nil repeats:YES];
You can't pass ur lable as parameter with selector...There should be either one parameter which will be id or no parameter..
here you have to use
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(movelabel:) userInfo:nil repeats:YES];
or
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(movelabel) userInfo:nil repeats:YES];
if you use the first on then you can get you timer and action defination will be like
- (void) moveLable :(id)sender {
}
sender will be timer.
anyways why you need your lable as parameter. you can directly access your lable if you declare it in .h file.