持有对使用闭包的本地对象的强引用 [Swift]

Holding a Strong ref to local object that uses closure [Swift]

我有一个关于使用闭包的本地对象的强引用的问题。 我有以下代码,其中对象 B 使用一个方法来关闭类型 A 的本地对象。 对象 A 中的方法使用异步操作执行一些网络任务,然后 return 对象 b 的闭包。 由于对象 A 在 B 中的方法中是本地的,并且由于我在对象 A 异步任务中使用 [weak self](以防止保留循环),因此对象被释放。

我应该在以下代码中更改什么以确保仅在关闭完成时才释放本地 A 对象?

这是重要代码的一部分:

class A {
    var restAPI: RestAPI?

    func fetchNews(completion: (_ json: [String:Any])->()) {
        // .....
        self.restAPI.fetch(url: url, results: { [weak self] (json) in // 
            completion(json)
        })
        // .....
    }
}

class B {
    // .... 
    // ... call to updateNews()

    func updateNews() {
        let aFetcher: A() 
        aFetcher.fetchNews(completion : { 
            // <<<< // aFetcher gets released and closue never called
            // parse...
        }
    }
}

您在 func updateNews()
的范围内将 aFetcher 声明为 let 当 updateNews() 的范围到达终点时,aFetcher 将被释放。 你的内部 fetch 函数中有 [weak self]。 在此阶段,aFetcher 将被释放,因为 updateNews() 已完成执行并且没有对该对象的强引用。

您只需要将变量 aFetcher 添加到 class B 以确保您对 aFetcher.

class B {

    // MARK: - Vars
    private let aFetcher = A()

    // MARK: - Public
    func updateNews() {
        aFetcher.fetchNews(completion : {
            // parse...
        }
    }
}

您需要对 class 的顶层进行强引用。

但是不要永久保留引用并可靠地保留和释放它在 class B 中添加一个可选的存储 属性 并在完成闭包中将其设置为 nil:

class B {

    var fetcher : A?

    // MARK: - Public
    func updateNews() {
        fetcher = A()
        fetcher!.fetchNews(completion : { [unowned self] in
            // parse...

            self.fetcher = nil
        }
    }
}