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

Swift线程安全Int变量实现方案:多线程增减+每秒自减至0通知

嘿,这个需求我刚好做过类似的,最优方案应该是结合GCD队列保证线程安全,搭配DispatchSourceTimer实现可靠的自动递减——既解决了多线程竞态问题,又能避免普通Timer的RunLoop依赖坑。下面给你详细拆解实现:

核心实现:线程安全计数器 + 自动递减通知
import Dispatch

class ThreadSafeCounter {
    // 用并发队列+barrier实现读写分离:读取可并发,写入排他,比纯串行队列效率更高
    private let syncQueue = DispatchQueue(label: "com.yourapp.ThreadSafeCounter.sync", attributes: .concurrent)
    private(set) var value: Int = 0
    
    // 自动递减计时器:用DispatchSourceTimer,比NSTimer更可靠,不受RunLoop模式限制
    private var timer: DispatchSourceTimer?
    
    // 两种通知方式:Block(推荐)和Selector
    var onZeroTriggered: (() -> Void)?
    weak var notificationTarget: NSObject?
    var notificationSelector: Selector?
    
    // MARK: - 初始化
    init(initialValue: Int = 0) {
        self.value = initialValue
        setupAutoDecrementTimer()
        
        // 初始值为0时直接触发通知
        if value == 0 {
            triggerZeroNotification()
        }
    }
    
    // MARK: - 线程安全操作方法
    func increment() {
        syncQueue.async(flags: .barrier) { [weak self] in
            self?.value += 1
            // 从0变回正数时重启计时器
            self?.restartTimerIfNeeded()
        }
    }
    
    func decrement() {
        syncQueue.async(flags: .barrier) { [weak self] in
            guard let self = self else { return }
            self.value -= 1
            self.checkAndHandleZeroState()
        }
    }
    
    func setValue(_ newValue: Int) {
        syncQueue.async(flags: .barrier) { [weak self] in
            guard let self = self else { return }
            self.value = newValue
            self.checkAndHandleZeroState()
        }
    }
    
    func getCurrentValue() -> Int {
        // 读取用同步操作,不阻塞写入队列
        return syncQueue.sync { value }
    }
    
    // MARK: - 计时器逻辑
    private func setupAutoDecrementTimer() {
        timer = DispatchSource.makeTimerSource(queue: syncQueue)
        timer?.schedule(deadline: .now() + 1, repeating: .seconds(1))
        timer?.setEventHandler { [weak self] in
            self?.decrement()
        }
    }
    
    private func restartTimerIfNeeded() {
        if value > 0 && timer?.isSuspended == true {
            timer?.resume()
        }
    }
    
    private func checkAndHandleZeroState() {
        if value == 0 {
            timer?.suspend()
            triggerZeroNotification()
        } else if value > 0 && timer?.isSuspended == true {
            timer?.resume()
        }
    }
    
    // MARK: - 通知触发
    private func triggerZeroNotification() {
        // 切回主线程触发,避免后台线程执行UI操作
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            // 优先触发Block
            self.onZeroTriggered?()
            // 再触发Selector(如果设置了)
            if let target = self.notificationTarget, let selector = self.notificationSelector {
                target.perform(selector)
            }
        }
    }
    
    // MARK: - 内存清理
    deinit {
        timer?.cancel()
    }
}
使用示例
// 1. 创建初始值为5的计数器
let counter = ThreadSafeCounter(initialValue: 5)

// 2. 设置Block通知
counter.onZeroTriggered = {
    print("计数器归零啦!")
    // 这里可以写UI更新逻辑,比如弹出提示
}

// 3. 或者设置Selector通知(适合OC风格调用)
counter.notificationTarget = self
counter.notificationSelector = #selector(handleCounterZero)

// 4. 在任意线程安全操作计数器
DispatchQueue.global().async {
    counter.increment() // 线程安全递增
}

DispatchQueue.global().async {
    let currentValue = counter.getCurrentValue() // 线程安全读取
    print("当前值:\(currentValue)")
}

// Selector回调实现
@objc func handleCounterZero() {
    print("Selector收到归零通知")
}
为什么这是最优方案?
  1. 线程安全保障:用GCD并发队列+barrier实现读写分离,读取操作可以并发执行,写入操作排他执行——比手动用NSLock更简洁,不容易出现锁遗漏或死锁问题,是Swift里推荐的线程同步方式。
  2. 计时器可靠性:DispatchSourceTimer基于GCD实现,不依赖RunLoop,即使在后台线程也能稳定运行,不会像NSTimer那样因为主线程RunLoop繁忙而延迟触发。
  3. 内存安全:全程用weak self避免循环引用,deinit里主动cancel计时器,防止内存泄漏。
  4. 灵活扩展:同时支持Block和Selector两种通知方式,还能轻松扩展批量增减、暂停/重启计时器等功能。
注意事项
  • 不要直接访问value变量,必须通过getCurrentValue()、increment()等方法操作,否则会破坏线程安全。
  • 如果允许计数器变为负数,需要调整checkAndHandleZeroState的逻辑,比如只有当值从正数降到0时触发通知。

内容的提问来源于stack exchange,提问作者kandaurov_net

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:05:01