常见延迟方式总结
本文列举了四种延时执行某函数的方法及其一些区别。假如延时1秒时间执行下面的方法。
- (void)delayMethod { NSLog(@"execute"); }
1.performSelector方法:(Swift中没有这个方法,因为在swift中这个方法是被认为是不安全的)
[self performSelector:@selector(delayMethod) withObject:nil afterDelay:1.0f];
此方式要求必须在主线程中执行,否则无效。
是一种非阻塞的执行方式,
暂时未找到取消执行的方法。
2.定时器:NSTimer
1 [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(delayMethod) userInfo:nil repeats:NO];
此方式要求必须在主线程中执行,否则无效。
是一种非阻塞的执行方式,
可以通过NSTimer类的- (void)invalidate;取消执行。
3. sleep方式
[NSThread sleepForTimeInterval:1.0f]; [self delayMethod];
此方式在主线程和子线程中均可执行。
是一种阻塞的执行方式,建方放到子线程中,以免卡住界面
没有找到取消执行的方法。
4.GCD方式
1 double delayInSeconds = 1.0; 2 3 __block ViewController* bself = self; 4 5 dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); 6 7 dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 8 9 [bself delayMethod]; });
此方式在可以在参数中选择执行的线程。
是一种非阻塞的执行方式,
没有找到取消执行的方法。
Swift中怎么实现
1.sleep
1 // 创建目标队列 2 let workingQueue = dispatch_queue_create("my_queue", nil) 3 4 // 派发到刚创建的队列中,GCD 会负责进行线程调度 5 dispatch_async(workingQueue) { 6 // 在 workingQueue 中异步进行 7 println("努力工作") 8 NSThread.sleepForTimeInterval(2) // 模拟两秒的执行时间 9 10 dispatch_async(dispatch_get_main_queue()) { 11 // 返回到主线程更新 UI 12 println("结束工作,更新 UI") 13 } 14 }
2.GCD
1 let time: NSTimeInterval = 2.0 2 let delay = dispatch_time(DISPATCH_TIME_NOW, 3 Int64(time * Double(NSEC_PER_SEC))) 4 dispatch_after(delay, dispatch_get_main_queue()) { 5 println("2 秒后输出") 6 }
封装一下
1 import Foundation 2 3 typealias Task = (cancel : Bool) -> () 4 5 func delay(time:NSTimeInterval, task:()->()) -> Task? { 6 7 func dispatch_later(block:()->()) { 8 dispatch_after( 9 dispatch_time( 10 DISPATCH_TIME_NOW, 11 Int64(time * Double(NSEC_PER_SEC))), 12 dispatch_get_main_queue(), 13 block) 14 } 15 16 var closure: dispatch_block_t? = task 17 var result: Task? 18 19 let delayedClosure: Task = { 20 cancel in 21 if let internalClosure = closure { 22 if (cancel == false) { 23 dispatch_async(dispatch_get_main_queue(), internalClosure); 24 } 25 } 26 closure = nil 27 result = nil 28 } 29 30 result = delayedClosure 31 32 dispatch_later { 33 if let delayedClosure = result { 34 delayedClosure(cancel: false) 35 } 36 } 37 38 return result; 39 } 40 41 func cancel(task:Task?) { 42 task?(cancel: true) 43 }
使用:
let task = delay(5) { println("拨打 110") }
// 仔细想一想..
// 还是取消为妙..
cancel(task)
时间: 2024-10-16 11:18:21