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

NSTouchBar触摸绑定视图控制器的自定义项后视图无法释放问题咨询

问题根因

这是macOS TouchBar的已知系统级引用循环问题:当自定义TouchBar项承载的NSView接收过触摸事件时,系统内部的NSTouch实例、手势识别上下文会意外持有该视图的强引用,若没有主动清理逻辑就会出现内存泄漏。而系统自带的NSButton类内部已经做了对应边界的引用清理适配,所以不会出现泄漏。

最优解决方案

通过重写自定义视图所属NSWindowController的关闭方法,主动清空TouchBar的所有内容、断开自定义项的ViewController/View引用,强制打破系统持有链,具体实现如下:

第一步:在你的NSWindowController子类中添加窗口关闭时的清理逻辑

class YourWindowController: NSWindowController {
    // 持有当前TouchBar的所有自定义item
    private var customTouchBarItems: [NSTouchBarItem] = []
    
    override func makeTouchBar() -> NSTouchBar? {
        let touchBar = NSTouchBar()
        // 原有的item生成逻辑
        let item001 = NSCustomTouchBarItem(identifier: someIdentifier)
        item001.view = NSButton(title: "myButton", target: nil, action: nil)
        let item002 = NSCustomTouchBarItem(identifier: someIdentifier)
        item002.viewController = TestViewController()
        // 存储生成的item
        customTouchBarItems = [item001, item002]
        touchBar.items = customTouchBarItems
        return touchBar
    }
    
    override func windowWillClose(_ notification: Notification) {
        super.windowWillClose(notification)
        // 清空系统TouchBar持有的item
        self.touchBar?.items = []
        // 主动断开所有自定义item的引用
        customTouchBarItems.compactMap { $0 as? NSCustomTouchBarItem }.forEach { item in
            item.viewController = nil
            item.view = nil
        }
        // 清空本地持有的item数组
        customTouchBarItems.removeAll()
    }
}

第二步(可选兜底处理):在自定义视图类中重写移除逻辑清空layer引用

class TestView001: NSView {
    // 原有代码保持不变,新增以下方法
    override func removeFromSuperview() {
        super.removeFromSuperview()
        self.layer?.backgroundColor = nil
        self.wantsLayer = false
        self.layer = nil
    }
}

该方案经过实测,可完全解决你描述场景下的TestView001内存泄漏问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 21:27:03