// 經典 API
[self performSelector:@selector(myMethod) withObject:nil afterDelay:23.0];
- (void)myMethod {
// 23 秒後執行
}
優點:簡單、單行程式碼。缺點:無法取消、無法傳遞多參數、不支援 Swift、RunLoop 模式敏感。
// Objective-C
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(23.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self myMethod];
});
// Swift
DispatchQueue.main.asyncAfter(deadline: .now() + 23.0) {
self.myMethod()
}
優點:可取消 (儲存 DispatchWorkItem)、支援閉包/多參數、主執行緒安全。
Timer.scheduledTimer(withTimeInterval: 23.0, repeats: false) { _ in
self.myMethod()
}
Task {
try await Task.sleep(nanoseconds: 23_000_000_000)
await MainActor.run { self.myMethod() }
}
class DelayExecutor {
private var workItem: DispatchWorkItem?
func execute(after delay: TimeInterval, block: @escaping () -> Void) {
cancel()
workItem = DispatchWorkItem(block: block)
DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: workItem!)
}
func cancel() {
workItem?.cancel()
workItem = nil
}
}
// 使用
let delay = DelayExecutor()
delay.execute(after: 23) { self.myMethod() }
// 需要取消時
delay.cancel()
| 場景 | 推薦方案 |
|---|---|
| 簡單一次性延遲、無需取消 | performSelector:afterDelay: / asyncAfter |
| 需取消/傳參/現代語法 | DispatchWorkItem / asyncAfter |
| 週期性/複雜排程 | Timer / DispatchSourceTimer |
| Swift 非同步流程中 | Task.sleep |
[weak self] in self?.method() 避免循環引用。Task.sleep 需 MainActor.run。拋棄 performSelector 這個 Objective-C 時代產物,擁抱 GCD/Swift Concurrency 的類型安全、可取消、可組合的現代非同步編程。