timers的替代方法
如果只是要延迟消息的发送,可以使用nsobject的方法
- (void)performselector:(sel)aselector withobject:(id)anargument afterdelay:(nstimeinterval)delay
- (void)performselectoronmainthread:(sel)aselector withobject:(id)arg waituntildone:(bool)wait
+ (void)cancelpreviousperformrequestswithtarget:(id)atarget
创建timer的三种方法
1.scheduling a timer with the current run loop
2.creating a timer that you later register with a run loop
3.initializing a timer with a given fire date
scheduled timers
以下两个方法自动注册新创建的timer到当前nsrunloop对象,nsrunloop的模式为默认的nsdefaultrunloopmode
+ (nstimer *)scheduledtimerwithtimeinterval:(nstimeinterval)seconds target:(id)target selector:(sel)aselector userinfo:(id)userinfo repeats:(bool)repeats
只发送一次
- (ibaction)startoneofftimer:sender {
[nstimer scheduledtimerwithtimeinterval:2.0
target:self
selector:@selector(targetmethod:)
userinfo:[self userinfo]
repeats:no];
}
重复发送消息
注:创建重复发送消息的timer一般需要保存一个引用,因为需要在某个时刻停止发送消息
- (ibaction)startrepeatingtimer:sender {
nstimer *timer = [nstimer scheduledtimerwithtimeinterval:0.5
target:self selector:@selector(timerfiremethod:)
userinfo:[self userinfo] repeats:yes];
self.repeatingtimer = timer;
unscheduled timers
创建未注册的timer,使用时调用addtimer:formode注册到nsrunloop对象
<a target="_blank">timerwithtimeinterval:target:selector:userinfo:repeats:</a>
timerwithtimeinterval:invocation:repeats:
- (ibaction)createunregisteredtimer:sender {
nsmethodsignature *methodsignature = [self methodsignatureforselector:@selector(invocationmethod:)];
nsinvocation *invocation = [nsinvocation invocationwithmethodsignature:methodsignature];
[invocation settarget:self];
[invocation setselector:@selector(invocationmethod:)];
nsdate *startdate = [nsdate date];
[invocation setargument:&startdate atindex:2];
nstimer *timer = [nstimer timerwithtimeinterval:0.5 invocation:invocation repeats:yes];
self.unregisteredtimer = timer;
- (ibaction)startunregisteredtimer:sender {
if (unregisteredtimer != nil) {
nsrunloop *runloop = [nsrunloop currentrunloop];
[runloop addtimer:unregisteredtimer formode:nsdefaultrunloopmode];
}
initializing a timer with a fire date
创建一个拥有指定发送日期的timer
- (ibaction)startfiredatetimer:sender {
nsdate *firedate = [nsdate datewithtimeintervalsincenow:1.0];
nstimer *timer = [[nstimer alloc] initwithfiredate:firedate
interval:0.5
target:self
selector:@selector(countedtargetmethod:)
userinfo:[self userinfo]
repeats:yes];
timercount = 1;
nsrunloop *runloop = [nsrunloop currentrunloop];
[runloop addtimer:timer formode:nsdefaultrunloopmode];
[timer release];
stopping a timer
- (ibaction)stoprepeatingtimer:sender {
[repeatingtimer invalidate];
self.repeatingtimer = nil;
也可以从timer发送的消息中停止timer
- (void)countedtargetmethod:(nstimer*)thetimer {
nsdate *startdate = [[thetimer userinfo] objectforkey:@"startdate"];
nslog(@"timer started on %@; fire count %d", startdate, timercount);
timercount++;
if (timercount > 3) {
[thetimer invalidate];
memory management
1. the run loop maintains the timer that is registered to it.
2. the timer is passed as an argument when you specify its method as a selector
3. you should maintain a strong reference to the unscheduled timer, in order to ensure that it's not deallocated before you use it.
4. a timer maintains a strong reference to its user info dictionary,
5. a timer maintains a strong reference to its target, so you should make sure that your timer's target survive longer than the timer itself.