我尝试实现一些Coordinator模式的变体,但是我面临封闭中保留周期的问题。看起来像这样:

func goTo() {
    let coord = SecondViewCoordinator(nav: navigationController)
    add(coord)
    coord.start()
    coord.deinitIfNeeded = { [weak self] in
        guard let self = self else { return }
        self.free(coord)
    }
}

如您所见,我设置了deinitIfNeeded,然后,如果在SecondViewCoordinator调用中正确弹出了deinitIfNeeded?()控制器,但是即使SecondViewCoordinator数组为空,对childCoordinators的引用仍然存在。

我的协调器类如下所示:

class Coordinator {

    weak var navigationController: UINavigationController?
    var childCoordinators: [Coordinator] = []
    var deinitIfNeeded: (() -> ())?

    init(nav: UINavigationController?) {
        self.navigationController = nav
    }

    func add(_ coordinator: Coordinator) {
        childCoordinators.append(coordinator)
    }

    func free(_ coordinator: Coordinator) {
        childCoordinators = childCoordinators.filter({ $0 !== coordinator })
    }
}

内存图显示以下内容:

ios - 保持关闭周期-LMLPHP

有任何想法吗?

最佳答案


coord.deinitIfNeeded = { [weak self] in
    guard let self = self else { return }
    self.free(coord)
}

您在闭包内部拥有对coord的强烈引用。尝试这样的事情;
coord.deinitIfNeeded = { [weak self, weak coord] in
    guard let self = self, let coord = coord else { return }
    self.free(coord)
}

内存图暗示了这种情况(右侧表示强引用位于闭包中)。

您还可以在闭包内部将coord.deinitIfNeeded设置为nil

10-07 23:01