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.