You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:42:23