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

带@objc修饰与无@objc的Swift函数区别及重复函数优化疑问

首先明确结论:Swift官方编程约定中没有要求保留两个逻辑完全相同的@objc函数和普通Swift函数,删除冗余实现、复用代码才是符合Swift代码简洁性、可维护性要求的最佳实践,保留两个重复实现仅为个人偏好,没有必须遵守的强制规则。

两种可选的优化方案

你可以根据后续业务迭代的可能性选择适配的方案:

  • 方案1:直接删除冗余的displayItems函数,统一调用带@objc修饰的方法,你也可以将方法名修改为更通用的语义,同时兼容初始化调用和通知回调的场景:
override func viewDidLoad() {
    super.viewDidLoad()
    configureNotifications()
    updateDisplayItems() // 直接调用@objc方法无任何限制
}

func configureNotifications() {
    NotificationCenter.default.addObserver(self, selector: #selector(updateDisplayItems), name: .updateExistingItem, object: nil)
}

/// 统一的列表刷新入口,支持Swift直接调用和通知回调
@objc func updateDisplayItems() {
    fetchLiveEvents { [weak self] in
        // 注意原代码中updateExistingItem的实现漏写了可选链?,这里补全避免崩溃
        self?.applySnapshot(animatingDifferences: true)
    }
}

注:@objc仅代表该方法会暴露给Objective-C运行时,完全支持正常的Swift语法调用,不会带来额外性能损耗或者功能异常。

  • 方案2:如果后续两个调用入口的逻辑可能出现差异,也可以将公共逻辑抽为私有方法,两个入口分别调用,同样不会有代码冗余:
override func viewDidLoad() {
    super.viewDidLoad()
    configureNotifications()
    displayItems()
}

/// 私有公共逻辑,仅内部调用
private func reloadLiveItemList() {
    fetchLiveEvents { [weak self] in
        self?.applySnapshot(animatingDifferences: true)
    }
}

/// 供Swift内部主动调用的刷新入口
func displayItems() {
    reloadLiveItemList()
}

/// 供通知中心回调的刷新入口
@objc func updateExistingItem() {
    reloadLiveItemList()
}

func configureNotifications() {
    NotificationCenter.default.addObserver(self, selector: #selector(updateExistingItem), name: .updateExistingItem, object: nil)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:54:01