項(xiàng)目開發(fā)中經(jīng)常會(huì)用到方法的延時(shí)調(diào)用臀蛛,具體的調(diào)用場(chǎng)景不做贅述荒椭,下面列舉現(xiàn)有的幾種實(shí)現(xiàn)方式:
1.performSelector
2.NSTimer
3.sleep
4.GCD
延遲執(zhí)行方法:
- (void)delayMethods{
NSLog(@"方法被延遲執(zhí)行");
}
方法一:performSelector
[self performSelector:@selector(delayMethods) withObject:nil afterDelay:1.0];
分析:該方法是一種非阻塞執(zhí)行方式啸驯,不會(huì)影響其他進(jìn)程跪妥;必須在主線程中執(zhí)行岳枷;
可以主動(dòng)取消操作:
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(delayMethods) object:nil];
如果要取消當(dāng)前所有延時(shí)操作:
[NSObject cancelPreviousPerformRequestsWithTarget:self];
注:該方法不夠安全漩蟆,這個(gè)方法在調(diào)用時(shí)會(huì)設(shè)置當(dāng)前runloop中的timer垒探。但是我們知道:只有主線程會(huì)在創(chuàng)建的時(shí)候默認(rèn)自動(dòng)運(yùn)行一個(gè)runloop,并含有timer怠李,普通的子線程是沒有runloop和timer的圾叼。所以在子線程中被調(diào)用的時(shí)候蛤克,我們的代碼中延時(shí)操作的代碼就會(huì)一直等待timer得調(diào)度,但是實(shí)際上子線程中沒有timer夷蚊,這就會(huì)導(dǎo)致我們的延時(shí)操作代碼永遠(yuǎn)都不會(huì)被執(zhí)行构挤。
方法二:NSTimer
NSTimer *timer =? [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(delayMethods) userInfo:nil repeats:NO];
分析:該方法是一種非阻塞執(zhí)行方式,不會(huì)影響其他進(jìn)程惕鼓;必須在主線程中執(zhí)行筋现;默認(rèn)為在主線程中設(shè)置一個(gè)定時(shí)器;可以設(shè)置是否重復(fù)執(zhí)行延時(shí)操作箱歧;
取消延時(shí)操作:[timer invalidate];
注:若repeats參數(shù)設(shè)置為NO矾飞,執(zhí)行完成后timer會(huì)自動(dòng)銷毀,如果repeats參數(shù)設(shè)置為YES呀邢,執(zhí)行完成后洒沦,必須手動(dòng)調(diào)用[timer invalidate]才能銷毀定時(shí)器;
方法三:sleep
[NSThread sleepForTimeInterval:1.0];
分析:該方法是一種阻塞執(zhí)行方式价淌,最好放在子線程中執(zhí)行微谓,否則會(huì)影響其他方法的執(zhí)行。
方法四:GCD
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self delayMethods];
});
分析:該方法是一種非阻塞執(zhí)行方式输钩,不會(huì)影響其他進(jìn)程豺型;可以在參數(shù)中設(shè)置執(zhí)行的進(jìn)程:
dispatch_queue_t queen = dispatch_get_global_queue(0, 0);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), queen, ^{
[self delayMethods];
});
也可以設(shè)置是否重復(fù)執(zhí)行:
__weak typeof(self) ws = self;
dispatch_queue_t queen = dispatch_get_global_queue(0, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queen);
if (timer) {
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 1.0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
[ws delayMethods];
});
dispatch_resume(timer);
}
注:因?yàn)樵摲椒ń唤o了GCD自動(dòng)處理,因此不容易取消操作买乃。