my app has a function, it gets a value from a NSTextField
and then declare the variable, like this:
- (IBAction)startTimer
//all the other code
int totalTime = secs + hoursInS开发者_Python百科econds + minutesInSeconds
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerHandler) userInfo:nil repeats:YES];
then, i want to use the local variable totalTime
in another function which processes the NSTimer
.
- (void)timerHandler
//all other code
totalTime = totalTime - 1;
//invalidate timer when it reaches 0
if (totalTime == 0.0) {
[timer invalidate];
however, as the variable totalTime is a local variable, i cannot use the value, and i cannot move the code over as NSTimer calls it every 1 sec and as the user may change the variable (and thus redeclaring it).
so, is there any way i can get a local variable from a function and implement the variable in another function which can be changed dynamically? or can i implement a NSTimer countdown by just using one function
You could wrap the value in the timer's userInfo
:
NSNumber *totalTimeNumber = [NSNumber numberWithInt:totalTime];
timer = [NSTimer scheduledTimerWithTimeInterval:... target:... selector:... userInfo:totalTimeNumber repeats:...];
Or just make it an instance variable.
Well, here's a fun one that works with local variables, instead of instance variables but only on Mac OS 10.6/iOS 4 and above:
-(IBAction)startTimer:(id)sender
{
// ensure, that the variables we'll capture in the block are mutable
__block int totalTime = ...
__block NSTimer *timer;
void (^timerBlock)() = ^{
if (--totalTime <= 0) { // this comparison is much less fragile...
[timer invalidate];
}
};
// If you'd call timerBlock() at this point you'll crash because timer contains junk!
// However, (since timer is declared as __block) we can give it a meaningful value now and have it updated inside of the block, as well:
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerHandler:) userInfo:timerBlock repeats:YES];
}
-(void)timerHandler:(NSTimer*)timer
{
((void (^)())[timer userInfo])(); // retrieve the block and run it
}
Caveat:
Since I'm sending this from my phone, I am not 100% sure about the cast in timerHandler:
. But it's something along this line...
You should be able to omit the cast altogether, but will definitely see a warning then.
精彩评论