Accessing instance variables from the NSTimer selector

First, a newbie question: what's the difference between a selector and a method?

Secondly, a question with a beginner (who would have thought): I need to encode some code based on instance variables and pause between loops until some condition is met (of course, based on instance variables). I looked at a dream, I looked at NSThread. In both discussions working through these options, many asked why I am not using NSTimer, so I am here.

Good, so just getting a method (selector?) To run on a schedule is enough. The problem is that I don’t know how to see the instance variables that I set outside the timer from the NSTimer code. I need to see these variables from the NSTimer selection code, as I 1) will update their values, and 2) will set labels based on these values.

Here is some code that shows the concept ... In the end, I would also invalidate myVariable timers, however I excluded this for the sake of clarity.

MyClass *aMyClassInstance = [MyClass new]; [aMyClassInstance setMyVariable:0]; [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(doStuff) userInfo:nil repeats:YES]; [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(doSomeOtherStuff) userInfo:nil repeats:YES]; - (void) doStuff { [aMyClassInstance setMyVariable:11]; // don't actually have access to set aMyClassInstance.myVariable [self updateSomeUILabel:[NSNumber numberWithInt:aMyClassInstance.myVariable]]; // don't actually have access to aMyClassInstance.myVariable } - (void) doSomeOtherStuff { [aMyClassInstance setMyVariable:22]; // don't actually have access to set aMyClassInstance.myVariable [self updateSomeUILabel:[NSNumber numberWithInt:aMyClassInstance.myVariable]]; // don't actually have access to aMyClassInstance.myVariable } - (void) updateSomeUILabel:(NSNumber *)arg{ int value = [arg intValue]; someUILabel.text = [NSString stringWithFormat:@"myVariable = %d", value]; // Updates the UI with new instance variable values } 
+4
source share
3 answers

You can use the userInfo parameter to pass an arbitrary object. In this case, you pass aMyClassInstance as userInfo:

 MyClass *aMyClassInstance = [MyClass new]; [aMyClassInstance setMyVariable:0]; [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(doStuff) userInfo:aMyClassInstance repeats:YES]; 

In the timer callback (which SHOULD accept the parameter), you return userInfo from the timer and say it:

 - (void) doStuff:(NSTimer *)timer { MyClass *instance = (MyClass *)[timer userInfo]; [instance setMyVariable:11]; [self updateSomeUILabel:[NSNumber numberWithInt:instance.myVariable]]; } 

It is clear that the timer saves the userInfo parameter.

+7
source

One of your questions asked a question about the difference between a selector and a method.

The selector "selects" the method to use with the object. Imagine you had animal classes, say Dog , Cat and Bird , all subclasses of Animal . They all implement a method called makeSound . Each class will have its own implementation of makeSound , otherwise all animals will sound the same. So all animals have a different method for making sound, but you get each animal to make its sound using the same selector. In other words, you choose the makeSound method of the animal.

+1
source

You have access to instance variables if you set the instance as a timer target as follows:

 [NSTimer scheduledTimerWithTimeInterval:1.0 target:aMyClassInstance selector:@selector(doStuff) userInfo:nil repeats:YES]; 

The instance (which you called aMyClassInstance ) will be self .


Alternatively, you can put aMyClassInstance and any other objects in the userInfo dictionary. You would do it like this:

 NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys: aMyClassInstance, @"a", bMyClassInstance, @"b", cMyClassInstance, @"c", nil]; [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(doStuff:) userInfo:userInfo repeats:YES]; 

Then in the doStuff: selector doStuff: you can return them like this:

 -(void) doStuff:(NSTimer*)timer; { MyClass* aMyClassInstance = [[timer userInfo] objectForKey:@"a"]; MyClass* bMyClassInstance = [[timer userInfo] objectForKey:@"b"]; MyClass* cMyClassInstance = [[timer userInfo] objectForKey:@"c"]; //do whatever you want here } 
0
source

Source: https://habr.com/ru/post/1311705/


All Articles