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

Swift中1秒未收事件时将@Published变量置为nil的最简实现方案

实现方案

你可以用苹果原生的Combine响应式框架实现,代码非常简洁,核心利用了流合并和防抖延迟的能力,完整代码如下:

import Combine

enum MyEnum {
    // 你的枚举定义
}

class MyController: NSObject, ObservableObject {
    @Published var myRapidlyChangingVar: MyEnum? = nil
    // 用于接收方法调用的事件流
    private let valueSubject = PassthroughSubject<MyEnum, Never>()
    private var cancellables = Set<AnyCancellable>()

    override init() {
        super.init()
        // 绑定流逻辑
        valueSubject
            .map { $0 as MyEnum? }
            // 合并两条流:1. 收到值立即发送当前值 2. 防抖1秒后发送nil
            .merge(
                with: valueSubject
                    .debounce(for: .seconds(1), scheduler: DispatchQueue.main)
                    .map { _ in nil }
            )
            .assign(to: \.myRapidlyChangingVar, on: self)
            .store(in: &cancellables)
    }

    func calledAtHighFrequencyByExternalEvents(value: MyEnum) {
        // 仅需要发送事件到流即可
        valueSubject.send(value)
    }
}

核心逻辑说明

  • 每次方法调用时会向事件流发送最新的枚举值,流会立即把值赋值给myRapidlyChangingVar
  • 同时debounce操作符会启动1秒计时,如果1秒内没有新的事件传入,就会发送nil重置变量
  • 如果1秒内有新的方法调用,会自动重置计时,完全符合连续1秒未调用才重置的需求
  • 你可以搜索Combine debounce、iOS idle timeout、Combine 延迟防抖作为相关关键词查询更多资料

非响应式的极简实现(GCD方案)

如果不想引入Combine,用GCD的DispatchWorkItem也可以实现,代码量更少:

class MyController: NSObject, ObservableObject {
    @Published var myRapidlyChangingVar: MyEnum? = nil
    private var pendingResetTask: DispatchWorkItem?

    func calledAtHighFrequencyByExternalEvents(value: MyEnum) {
        myRapidlyChangingVar = value
        // 取消上一次未执行的重置任务
        pendingResetTask?.cancel()
        // 创建新的重置任务
        let resetTask = DispatchWorkItem { [weak self] in
            self?.myRapidlyChangingVar = nil
        }
        pendingResetTask = resetTask
        DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: resetTask)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 15:54:10