为什么将弱引用的self传递给静态函数闭包会导致保留环产生?

3

只要我不注释掉下面的函数,我的AchievementViewController就不会从内存中被释放

    NetworkConnection.achievementList(for: -1) { [weak self] response in
        guard let sections = response.object as? [AchievementListSection] else {
            return print("Network failure")
        }
        self?.sections = sections
        self?.configureCollectionView()
    }

这个函数的定义如下,在目前,我们只是使用一个延迟的异步调用来发送一个存根化的响应。
static func achievementList(for identifier: Int64, responseHandler: RequestResponseClosure?) {
    let stubResponse = ResponseObject(object: AchievementListSection.exampleList as NSArray, code: .success)
    let randomDelayMilliseconds = Int(arc4random_uniform(1000))
    DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(randomDelayMilliseconds)) {
        responseHandler?(stubResponse)
    }
}

在这里,self被保留在哪里以创建一个循环呢?它被作为弱引用传递给NetworkConnection闭包,当这个闭包传递给DispatchQueue后,我期望它会在延迟过后释放。


2
你在闭包中捕获 weak self 这一事实应该可以防止任何 achievementList 实现方式产生保留循环。你确定这个闭包是有问题的吗?该问题不可能从其他地方开始吗? - Cristik
@Cristik 很不幸我非常确定。如果我注释掉这个函数,视图控制器就会被释放。如果不注释它,视图控制器就永远不会被释放。 - Declan McKenna
3
尝试注释掉 self?.configureCollectionView() 看看是否是问题所在。 - Kstin
@Kstin 啊,谢谢。我一直在走弯路。请放心将其作为答案,我会标记它为正确的。 - Declan McKenna
1个回答

2

尝试注释此行

self?.configureCollectionView() 

可能是这个问题,因为在这个闭包中使用[weak self]就足以解决保留问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接