I've been trying to figure out how to setup an NSTimer to allow me to print the current time in a UILabel within a View, and have it update every second (no finer resolution required - just a simple clock).
At first, I wasn't using a NSRunLoop, but if I try and include one, the execution just "spins" inside the loop, blocking further execution. I have posted my code below.
-(id) printCurrentTime {
now = [NSDate date];
dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setTimeStyle:NSDateFormatterMediumStyle];
NSString *nowstr = [dateFormat stringFromDate:now];
[dateFormat release];
NSLog(@"Current time is: %@",nowstr);
return nowstr;
}
And in the ViewController source file, I execute as per:
TimeStuff *T = [[TimeStuff alloc] init];
NSString *thetime = [T printCurrentTime];
[timelabel setText:thetime];
[T release];
[self.view addSubview:timelabel];
NSTime开发者_JS百科r *timmeh = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(printCurrentTime) userInfo:nil repeats:YES];
[[[NSRunLoop currentRunLoop] addTimer:timmeh forMode:NSDefaultRunLoopMode] run];
The "TimeStuff" class is effectively an empty class, save for the printCurrentTime function.
Questions:
1) Should I be including the RunLoop in the AppDelegate class? I am having trouble visualising how this all should hang together, as in - what are the steps to achieving a Loop based on Timer to update a text label with the up-to-second time. Pretty stumped.
2) In the event that I should use a NSThread, should that also be in it's own class / the Delegate class.
3) Is the ViewController class totally out of bounds for looping/timers, and simply the "eye candy" class, with callbacks to functions in the Delegate class?
Thank you for your time and patience.
You don't need to deal with run loops at all.
This line :
NSTimer *timmeh = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(printCurrentTime) userInfo:nil repeats:YES];
will create a timer and attach it to the current thread's run loop for you. You don't need the [NSRunLoop addTimer:forMode:]
call at all - you can delete that line.
PS You certainly don't need to go as far as NSThreads!
EDIT Regarding your comment :
You will need to make an instance of your TimeStuff class for the timer to use if that's where your printCurrentTime method is. i.e.
@interface MyViewController : UIViewcontroller {
TimeStuff *timeStuff
}
and in your viewDidLoad method:
- (void)viewDidLoad {
[super viewDidLoad];
...
// Create our timestuff if we don't have one already
if (nil == timeStuff)
timeStuff = [[TimeStuff alloc] init];
// Start the timer
[NSTimer scheduledTimerWithTimeInterval:1.0 target:timeStuff selector:@selector(printCurrentTime) userInfo:nil repeats:YES];
and not forgetting dealloc
- (void)dealloc {
[timeStuff release];
...
[super dealloc];
}
Passing in the timeStuff as the target for the timer tells it where to look for the printCurrentTime method!
Hope that helps,
PS All the line @class TimeStuff
does is tell the compiler that there is a class called TimeStuff. It has no idea that you want to use it for your timer's selector!
精彩评论