Ahoura Ghotbi
Ahoura Ghotbi

Reputation: 2896

NSTimer doesn't pass arguments to the selector

I create an NSTimer:

    [NSTimer scheduledTimerWithTimeInterval:2.0
                                     target:self
                                   selector:@selector(createObject:)
                                   userInfo:nil
                                    repeats:YES];

and createObject: is defined as follows:

- (void)createObject:(ccTime) dt{

    int r = arc4random() % 4;


    for (int i=0; i < r; i++) {

    character[charIndex] = [CCSprite spriteWithFile:@"o.png"];

    }
}

What I want to achieve is to send some variables into the method. I rewrote the function as:

- (void)createObject:(ccTime) dt cID:(int)cID {

    int r = arc4random() % 4;


    for (int i=0; i < r; i++) {

    character[cID] = [CCSprite spriteWithFile:@"o.png"];

    }
}

but I can't pass the variable cID to the function from the timer. Is it possible to do this?

Upvotes: 4

Views: 7050

Answers (5)

Oleh Kudinov
Oleh Kudinov

Reputation: 2543

You can pass your parameters with userInfo:[NSDictionary dictionaryWithObjectsAndKeys:parameterObj1, @"keyOfParameter1"...

A simple example:

[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(handleTimer:) userInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:9], @"parameter1", nil] repeats:YES];


-(void) handleTimer:(NSTimer *)timer{


    int parameter1 = [[[timer userInfo] objectForKey:@"parameter1"] integerValue];

    if(parameter1>0){

        [timer invalidate];
        timer=nil;
   }
}

Upvotes: 1

Matthias Bauch
Matthias Bauch

Reputation: 90117

according to the documentation methods that are called from a NSTimer need a signature like this:

- (void)timerFireMethod:(NSTimer*)theTimer

It is not possible to provide custom parameters, or more than one parameter.


So rewrite your timer method so it uses the userInfo of the NSTimer

- (void)createObject:(NSTimer *)timer {
    NSDictionary *userInfo = [timer userInfo];
    int cID = [[userInfo objectForKey:@"cID"] intValue];
    /* ... */
}

create a userInfo and then start the timer like this:

NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
                          [NSNumber numberWithInt:cID], @"cID",
                          /* ... */
                          nil];
[NSTimer scheduledTimerWithTimeInterval:2.0
                                 target:self
                               selector:@selector(createObject:)
                               userInfo:userInfo
                                repeats:YES];

Upvotes: 17

hotpaw2
hotpaw2

Reputation: 70733

The userInfo parameter has to be an object. Other data types ( such as a C data tyoe) need to be wrapped inside an object, or dictionary or array of objects.

Upvotes: 0

JeremyP
JeremyP

Reputation: 86691

An alternative method to using +scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: is to use +scheduledTimerWithTimeInterval:invocation:repeats:. An NSInvocation can wrap any method signature and parameters. It is however, more complicated to set up than just setting userInfo to a dictionary containing the things you want.

Upvotes: 1

Vincent Bernier
Vincent Bernier

Reputation: 8664

Your selector must have this signature :

- (void)timerFireMethod:(NSTimer*)theTimer

But there is a concept of UserInfo in Cocoa

userInfo :
The user info for the timer. The object you specify is retained by the timer and released when the timer is invalidated. This parameter may be nil.

So in clear you can use that to pass information to the method that is call by the timer and from that method you can access the UserInfo.

information = [theTimer userInfo];

Upvotes: 7

Related Questions