Call class method from non-class method - objective-c

The following piece of code refuses to compile because the method: "FollowPlayer" is a class method with class level access. How do I correctly allow NSTimer to call +(void)FollowPlayer?
- (void)awakeFromNib{zombie_size=4; timer=[NSTimer scheduledTimerWithInterval: 1.0 target:self selector:#selector(FollowPlayer) userInfo:nil repeats: NO];}
+ (void)FollowPlayer: NSTimer{}

Change the target from 'self' to [MyClass class] where MyClass is the name of your class.

Hey. Can you check that the method you are calling is scheduledTimerWithTimeInterval ? Your code has it calling scheduledTimerWithInterval ... missing the Time part

Are you sure it's not just a syntax error? Can you do this?
- (void)awakeFromNib{zombie_size=4; timer=[NSTimer scheduledTimerWithInterval: 1.0 target:self selector:#selector(FollowPlayer:) userInfo:nil repeats: NO];}
+ (void)FollowPlayer:(id)userInfo { NSLog(#"Timer called with user info %#", userInfo); }

Related

Passing an argument with an NSTimer and from a regular call to the same method

I need to pass an integer to my method startEvent:. The method is a timer's action method. I've read about how to pass data with userInfo, however I don't understand how to do that so I can still call the method as I'd normally do.
How do I pass integers from an NSTimer and from a regular call to the same method?
[NSTimer scheduledTimerWithTimeInterval:0.032f target:self selector:#selector(startEvent:) userInfo:nil repeats:NO];
[self startEvent: 0];
-(void)startEvent:(int) event {
// ...
}
Use a pass-through for the timer's action method:
- (void)startEventFromTimer:(NSTimer *)tim
{
[self startEvent:[[tim userInfo] intValue]];
}
Where your timer was created with an NSNumber for its user info object.
[NSTimer scheduledTimerWithTimeInterval:0.032f
target:self
selector:#selector(startEventFromTimer:)
userInfo:#(theIntYouWantToPass)
repeats:NO];
You are starting from a fundamental misunderstanding. Your method cannot be the timers action method unless it conforms to the documented signature.
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html
(void)timerFireMethod:(NSTimer *)timer
The only opportunity you have to pass additional information in is via the userinfo object, as Josh Caswells answer demonstrates.

How to call a method every x seconds in Objective-C using NSTimer?

I am using Objective-C, Xcode 4.5.1 and working on an app for the iPhone.
I have a method A in which I want to call another method B to do a series of calculations every x seconds. In method A I start playing an audio file. Method B will monitor the audio every x seconds for the duration of the audio file.
I have found NSTimer as a potential solution, but am having a hard time getting it to work/understanding it.
I simply want to call Method B every x seconds and run its calculations, but NSTimer requires me to provide several things of which I'm not sure what I'm supposed to tell it.
[NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)
target:(id) select:(SEL) userInfo:(id) repeats:(BOOL)];
It is my understanding that at NSTimeInterval I provide the interval at which I want NSTimer to operate. But, how do I tell it to run Method B?
I have looked at example code, and am currently under the impression that I provide the method at the 'select:'. But, what do I write at the 'target:'? Why would I need a target? I tried entering 'self', but Xcode tells me:
Use of undeclared identifier 'self'
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
select:#selector(targetMethod:myVolumeMonitor()) userInfo:nil repeats:YES];
So, I figure 'self' is supposed to be a pointer to an object, but where do I want to point to?
Below is a simplification of my code:
MethodA()
{
//Start playing an audio file.
//NSTimer calling Method B, as long the audio file is playing, every x seconds.
}
MethodB()
{
//Do calculations.
}
I would be grateful if somebody could provide me with some answers/point me in the right direction! (:
Target is the recipient of the message named in select.
In Objective-C functions are not called. There are rather messages sent to objects. The Object internally refers to its symbol table and determines which of its methods is being called. That is a selector. Your selector is #selector(MethodB).
(BTW: you should start method names with lower case. "methodB" would be more appropriate here.)
This leads to the question: how to determine the object to which the message is sent? That is the target. In your case, it is simply self.
BTW: In this case the selector is expected to return void and accept an id, which is the id of the NSTimer object itself. That will come handy if you want the timer to stop firing based on some conditions according to your program logic.
Most important: Your selector is then methodB: rather than methodB.
- (void) methodA
{
//Start playing an audio file.
//NSTimer calling Method B, as long the audio file is playing, every 5 seconds.
[NSTimer scheduledTimerWithTimeInterval:5.0f
target:self selector:#selector(methodB:) userInfo:nil repeats:YES];
}
- (void) methodB:(NSTimer *)timer
{
//Do calculations.
}
try this
NSTimer *aTimer = [NSTimer timerWithTimeInterval:(x) target:self selector:#selector(timerFired:) userInfo:nil repeats:YES];
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:aTimer forMode: NSDefaultRunLoopMode];
[popUpImageView release];
- (void)timerFired:(NSTimer*)theTimer
{
if(condition)
{
[theTimer isValid]; //recall the NSTimer
//implement your methods
}
else
{
[theTimer invalidate]; //stop the NSTimer
}
}
If you look at your code and compared to the one below
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
select:#selector(targetMethod:myVolumeMonitor()) userInfo:nil repeats:YES];
self means that you are invoking a method in same instance of your class, in your example the method is myVolumeMonitor
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self
selector:#selector(MethodB) userInfo:nil repeats:YES];
and you are good to go though
method be should look like this
- (void)MethodB:(NSTimer*)timer {
// do something
}
Well you are trying to call an normal C method, NSTimer can't to that.
The target is the an instance of the class on which to call the selector, this selector adn not select. The selector here is a SEL type which you can create with the #selector(METHOD_NAME) function.
For example this will call the handleTimer : ever 0.1 second: (For this example the AppDelegate is used):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//SNIP, some code to setup the windos.
[NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:#selector(handleTimer:) userInfo:nil repeats:YES];
return YES;
}
- (void) handleTimer:(NSTimer *)timer {
// Hanlde the timed event.
}

using #selector in a class IOS

Im making a class that creates a timer that then calls a void using #selector or (SEL). The app crashes when [mytimer timer…]; is called because "unknown selector called". The error is that it isnt finding the void I'm giving to it but i know that the void works fine. My question is how to I write the myselector part correctly?
+ (void) timer:(NSTimer*)timer interval:(int)interval selector:(SEL)myselector
{
timer = [NSTimer scheduledTimerWithTimeInterval:interval
target:self
selector:myselector
userInfo:nil
repeats:YES];
}
This is the method being implemented:
[mytimer timer:NameOfTimerTheWorks interval:0.1 selector:#selector(myVoid)];
...
- (void)myVoid
{
Do stuff
}
Also I understand that this class looks completely useless but there is more to it that I didnt include. My problem revolves around the selector.
There's nothing wrong with your use of #selector(), your issue is with Objective C classes, and what self means in different scopes.
The problem is that you're creating your timer in a class + method and self at that point is not the instance you want, it's actually the Class itself. I wouldn't be doing it in a class method, but if you must, just pass in the reference to the target and it should send th message your'e expecting.
Change your implementation to the following so you pass in the target, and return the timer
+ (NSTimer *)timerWithTarget:(id)target
interval:(int)interval
selector:(SEL)myselector
{
return [NSTimer scheduledTimerWithTimeInterval:interval
target:target
selector:myselector
userInfo:nil
repeats:YES];
}
NameOfTimerTheWorks = [mytimer timetWithTarget:self interval:0.1 selector:#selector(myVoid)];
- (void)myVoid
{
//Do stuff
}
Additionally, in Objective C the standard way to name classes is with a capital letter, and camel case where appropriate. Your class should be MyTimer and not mytimer and iVars are lowercase eg nameOfTimerTheWorks.
I believe the problem is that you're trying to access an instance level method using a class level method.
I changed + to - so that it was an instance level method.
If you wanted your method to be class level it would require that you make the method you want to call also class level.
- /* <-- + */(void) timer:(NSTimer*)timer interval:(int)interval selector:(SEL)selector
{
timer = [NSTimer scheduledTimerWithTimeInterval:interval
target:self
selector:selector
userInfo:nil
repeats:YES];
}

Passing object to method in NSTimer

This is a really dumb question. How would you pass an object to a method using an NSTimer?
I mean something like this -
I have a method in BigView.m that has a method called doSomethingWithClass:.
- (void)doSomethingWithClass:(CustomClass *)class {
NSLog(#"Something was done");
}
In another class called CustomClass, I have an NSTimer -
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:bigView selector:#selector(doSomethingWithClass:) userInfo:nil repeats:NO];
Where bigView is an instance of BigView. Now I want to pass an entire instance of CustomClass as the parameter in the method doSomethingWithClass:. How do I do it?
If you don't need to refer to the timer, use the simpler performSelector:withObject:afterDelay: method.
[bigView performSelector:#selector(doSomethingWithClass:)
withObject:customClass
afterDelay:0.5];
(To cancel it, use +cancelPreviousPerformRequestsWithTarget:….)

Objective C: Call variable from another method

I'm trying to access an NSTimer in a method called getTimer in another method.
- (NSTimer *)getTimer{
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector: #selector(produceBricks) userInfo:nil repeats:YES];
return timer;
[timer release];
}
I'm trying to stop the timer in another method (a method that would pause the game) by using:
if ([getTimer.timer isValid]) {
[getTimer.timer invalidate];
}
I'm assuming this is not the correct syntax being it tells me getTimer is undeclared. How would I access the timer so I can stop it?
getTimer is a method, not an object, so you can't send messages to it or access properties. Rather, assuming that the method is in the same class as the one calling it, you would call it like this:
NSTimer *timer = [self getTimer];
if ([timer isValid]) [timer invalidate];
//...
Also, you're trying to release your timer in the getTimer method after the return statement. This code will never be executed (the method has already ended) - which is good in this case, because you shouldn't release the timer, it's already autoreleased. I'd recommend that you read something on Objective-C memory management and naming conventions.
Make the timer an instance variable instead of creating in within getTimer. Then it will be accessible anywhere within the class as follows:
in MyClass.h
NSTimer* timer;
I would implement a startTimer and stopTimer method.
- (void) startTimer {
timer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector: #selector(produceBricks) userInfo:nil repeats:YES];
}
- (void) stopTimer {
if([timer isValid]) {
[timer invalidate];
}
}