建筑师之家IOS / NOTES
← 全部笔记

性能

泄漏先查谁把谁留住了

闭包、定时器、委托默认是强引用。退了页面内存不掉,就从引用关系往回看。

页面 pop 之后,Memory Graph 里这个控制器还在,就是被留下了。先找入边,不要先加 autoreleasepool。多数时候是闭包、Timer、通知、或者一个没断掉的委托。

闭包

逃逸闭包默认强引用 self。请求回调、动画完成、Combine 的 sink,都会把控制器留到回调结束。如果回调的生命周期比页面长,页面就泄漏。

final class EditorController: UIViewController {
    private var saveTask: Task<Void, Never>?

    func save() {
        saveTask = Task { [weak self] in
            guard let self else { return }
            await self.store.save()
        }
    }

    deinit {
        saveTask?.cancel()
    }
}

weak 解决的是环,不是所有捕获。如果闭包执行时页面必须还在,用 weak 后 guard 失败就返回,比强引用把页面钉死更合适。deinit 里取消任务,避免回调打到一半。

另外三条

确认方法:推入页面,退出,看这个类的实例数是否回到原来。增长一次就查一次,不要等内存警告再翻整张图。