iOS开发之-Timer

Alternatives to Timers

If you simply want to send a message at some point in the future, you can do so without using a timer. You can use performSelector:withObject:afterDelay: and related methods to invoke a method directly on another object. Some variants, such as performSelectorOnMainThread:withObject:waitUntilDone:, allow you to invoke the method on a different thread. You can also cancel a delayed message send using cancelPreviousPerformRequestsWithTarget: and related methods.

Creating and Scheduling a Timer

1. There are, broadly speaking, three ways to create a timer: scheduling a timer with the current run loop; creating a timer that you later register with a run loop; and initializing a timer with a given fire date. 


2. If you specify the selector for the message directly, the name of the method does not matter but it must have the following signature:

- (void)timerFireMethod:(NSTimer*)theTimer


@interface TimerController : NSObject {
    NSTimer *repeatingTimer;
    NSTimer *unregisteredTimer;
    NSUInteger timerCount;
}
 
@property (assign) NSTimer *repeatingTimer;
@property (retain) NSTimer *unregisteredTimer;
@property NSUInteger timerCount;
 
- (IBAction)startOneOffTimer:sender;
 
- (IBAction)startRepeatingTimer:sender;
- (IBAction)stopRepeatingTimer:sender;
 
- (IBAction)createUnregisteredTimer:sender;
- (IBAction)startUnregisteredTimer:sender;
- (IBAction)stopUnregisteredTimer:sender;
 
- (IBAction)startFireDateTimer:sender;
 
- (void)timerFireMethod:(NSTimer*)theTimer;
- (void)invocationMethod:(NSDate *)date;
- (void)countedTimerFireMethod:(NSTimer*)theTimer;
 
- (NSDictionary *)userInfo;
 
@end

- (NSDictionary *)userInfo {
    return [NSDictionary dictionaryWithObject:[NSDate date] forKey:@"StartDate"];
}
 
- (void)targetMethod:(NSTimer*)theTimer {
 
    NSDate *startDate = [[theTimer userInfo] objectForKey:@"StartDate"];
    NSLog(@"Timer started on %@", startDate);
}
 
- (void)invocationMethod:(NSDate *)date {
 
    NSLog(@"Invocation for timer started on %@", date);
}

Scheduled Timers

The following two class methods automatically register the new timer with the current NSRunLoop object in the default mode (NSDefaultRunLoopMode):

- (IBAction)startOneOffTimer:sender {
 
    [NSTimer scheduledTimerWithTimeInterval:2.0
             target:self
             selector:@selector(targetMethod:)
             userInfo:[self userInfo]
             repeats:NO];
}

The timer is automatically fired by the run loop after 2 seconds, and is then removed from the run loop.


- (IBAction)startRepeatingTimer:sender {
 
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.5
                              target:self selector:@selector(timerFireMethod:)
                              userInfo:[self userInfo] repeats:YES];
    self.repeatingTimer = timer;
}

Stopping a Timer

If you create a non-repeating timer, there is no need to take any further action. It automatically stops itself after it fires. If you create a repeating timer, however, you stop it by sending it an invalidate message. You can also send a non-repeating timer an invalidate message before it fires to prevent it from firing.

- (IBAction)stopRepeatingTimer:sender {
    [repeatingTimer invalidate];
    self.repeatingTimer = nil;
}
 
- (IBAction)stopUnregisteredTimer:sender {
    [unregisteredTimer invalidate];
    self.unregisteredTimer = nil;
}

Memory Management

Because the run loop maintains the timer, from the perspective of memory management there's typically no need to keep a reference to a timer after you’ve scheduled it. Since the timer is passed as an argument when you specify its method as a selector, you can invalidate a repeating timer when appropriate within that method. In many situations, however, you also want the option of invalidating the timer—perhaps even before it starts. In this case, you do need to keep a reference to the timer, so that you can send it an invalidate message whenever appropriate. If you create an unscheduled timer, then you must maintain a strong reference to the timer (in a reference-counted environment, you retain it) so that it is not deallocated before you use it.

Perhaps more importantly, a timer also maintains a strong reference to its target. This means that as long as a timer remains valid (and you otherwise properly abide by memory management rules), its target will not be deallocated. As a corollary, this means that it does not make sense for a timer’s target to try to invalidate the timer in its dealloc or finalize method—neither method will be invoked as long as the timer is valid.
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值