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

如何为直接赋值给闭包变量的函数设置weak self,实现相同内存管理效果

解决实例方法赋值闭包导致的循环引用问题

问题原因

直接将TabController的实例方法changeTab赋值给tabView.itemTapped时,实例方法会隐式捕获当前self(即TabController实例),形成循环引用链:TabController持有TabView,TabView的itemTapped闭包持有TabController,导致两者都无法被ARC自动释放。

实现示例1写法的内存安全版本

要保持直接赋值方法的简洁性,同时避免循环引用,可以通过自定义工具方法将实例方法包装为弱引用闭包:

步骤1:添加泛型工具方法

写一个全局泛型函数,用来将实例方法转换为带weak self的闭包:

func weaklyCaptured<T: AnyObject, Args>(_ instance: T, method: @escaping (T) -> (Args) -> Void) -> (Args) -> Void {
    return { [weak instance] args in
        guard let instance = instance else { return }
        method(instance)(args)
    }
}

步骤2:修改示例1的赋值方式

在setupViewActions中,用这个工具方法包装changeTab方法:

func setupViewActions() {
    // 此写法和示例2一样能正常释放TabController
    tabView.itemTapped = weaklyCaptured(self, method: TabController.changeTab)
}

完整修正后的代码

class TabController: UITabBarController {
    var tabView: TabView = TabView() // 假设已完成初始化

    func setupViewActions() {
        // 修正后的无循环引用写法
        tabView.itemTapped = weaklyCaptured(self, method: TabController.changeTab)

        // 原示例2的安全写法(对比参考)
        tabView.itemTapped = { [weak self] tab in
            self?.changeTab(tab: tab)
        }
    }

    func changeTab(tab: TabItem) {
        self.selectedIndex = tab.index
    }
}

enum TabItem {
    case home, profile
    var index: Int { // 修正Swift类型名大小写
        switch self {
        case .home: return 0
        case .profile: return 1
        }
    }
}

class TabView: UIView {
    var itemTapped: ((_ tab: TabItem) -> Void)?
}

// 全局泛型工具方法
func weaklyCaptured<T: AnyObject, Args>(_ instance: T, method: @escaping (T) -> (Args) -> Void) -> (Args) -> Void {
    return { [weak instance] args in
        guard let instance = instance else { return }
        method(instance)(args)
    }
}

原理说明

  • 工具方法weaklyCaptured接收实例和对应的类方法引用(TabController.changeTab是类级别的方法引用,不会直接捕获实例),返回一个新闭包。
  • 返回的闭包通过[weak instance]弱引用捕获原实例,当实例被释放时,闭包内的instance会变为nil,自动终止方法调用,从而打破循环引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:08:30