如何在不使用Timer的情况下每秒发送3次URL请求?
不用Timer实现每秒3次URL请求的Swift方案
好的,我来帮你搞定这个需求——不用Timer实现每秒3次URL请求,同时结合你给出的代码片段做优化和完善。
首先你的思路用OperationQueue控制请求串行执行是对的,但有个小细节要调整:别用OperationQueue.main作为URLSession的delegate队列,主队列是处理UI事件的,把后台请求的回调放在这里可能拖慢UI响应,建议用自定义的后台串行队列。
下面是完整的实现方案,核心思路是:利用串行队列的特性,每次请求完成后延迟约333毫秒(1/3秒)再发起下一次请求,通过递归调用实现循环,完全不需要Timer。
完整代码示例
import Foundation class RequestScheduler: NSObject, URLSessionDataDelegate { // 自定义后台串行队列,保证请求按顺序执行 private let operationQueue: OperationQueue = { let queue = OperationQueue() queue.maxConcurrentOperationCount = 1 queue.qualityOfService = .background return queue }() private var urlSession: URLSession! // 控制请求循环的开关,方便随时启停 private var shouldKeepRequesting = true override init() { super.init() // 初始化URLSession,绑定自定义队列作为delegate队列 urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: operationQueue) } // 启动请求循环 func startRequestCycle() { shouldKeepRequesting = true sendNextRequest() } // 停止请求循环 func stopRequestCycle() { shouldKeepRequesting = false } private func sendNextRequest() { guard shouldKeepRequesting else { return } // 替换成你的目标请求URL guard let targetUrl = URL(string: "https://your-api-endpoint.com") else { print("无效的请求URL") scheduleNextRequest() return } let task = urlSession.dataTask(with: targetUrl) { [weak self] data, response, error in // 处理请求结果的逻辑放在这里 if let error = error { print("请求失败: \(error.localizedDescription)") } else if let data = data, let httpResponse = response as? HTTPURLResponse { print("请求成功,状态码: \(httpResponse.statusCode),数据长度: \(data.count)") // 解析返回数据的代码写在这里 } // 请求完成后,调度下一次请求 self?.scheduleNextRequest() } task.resume() } private func scheduleNextRequest() { // 每秒3次,间隔约333毫秒 let interval = DispatchTimeInterval.milliseconds(333) // 用全局队列调度延迟,避免阻塞请求队列 DispatchQueue.global().asyncAfter(deadline: .now() + interval) { [weak self] in self?.sendNextRequest() } } } // 使用示例 let scheduler = RequestScheduler() scheduler.startRequestCycle() // 需要停止时调用:scheduler.stopRequestCycle()
关键细节说明
- 自定义串行队列:既保证请求按顺序执行,避免并发过多导致的服务端压力,又不会占用主队列资源影响UI流畅度。
- 递归调度逻辑:每次请求完成后通过
asyncAfter延迟指定时间再发起下一次,精准控制每秒3次的频率,完全不需要Timer。 - 内存安全:用
[weak self]避免循环引用,防止内存泄漏。 - 灵活可控:通过
shouldKeepRequesting开关可以随时启动或停止请求循环,适配不同业务场景。
内容的提问来源于stack exchange,提问作者Bogdan Bogdanov
相关产品推荐
相关产品推荐

