Swift:嵌套闭包中的自引用
Posted
技术标签:
【中文标题】Swift:嵌套闭包中的自引用【英文标题】:Swift: self reference in nested closures 【发布时间】:2018-10-22 18:54:40 【问题描述】:我在 Swift 中使用新的基于块的 KVO API 来观察属性。 下面是示例代码。
class A: NSObject
var observerA: NSKeyValueObservation? = nil
var observerB: NSKeyValueObservation? = nil
var property1: CustomObj1?
var property2: CustomObj2?
func doSomething()
func doSomethingElse()
func observeValues()
observerA = customObj1.observe(\.property1, options: [], changeHandler: [weak self] (obj, change) in
guard let strongSelf = self else return
strongSelf.doSomething()
strongSelf.observerB = customObj2.observe(\.property2, options: [], changeHandler: [weak strongSelf] (nestedObj, nestedChange) in
guard let nestedStrongSelf = strongSelf else return
nestedStrongSelf.doSomethingElse()
)
)
我的问题是我们如何在内部更改处理程序块中引用self
。
我可以像上面那样使用它,而且我没有看到任何内存泄漏。但是在内部更改处理程序的“[weak strongSelf]”中使用self
代替strongSelf
也不会导致任何问题。这是代码。
func observeValues()
observerA = self.observe(\.property1, options: [], changeHandler: [weak self] (obj, change) in
guard let strongSelf = self else return
strongSelf.doSomething()
strongSelf.observerB = strongSelf.observe(\.property2, options: [], changeHandler: [weak self] (nestedObj, nestedChange) in
guard let nestedStrongSelf = self else return
nestedStrongSelf.doSomethingElse()
)
)
我的问题是如何在嵌套的完成处理程序中引用 self
,以及这方面的最佳实践是什么。谢谢。
【问题讨论】:
我为我之前的错误回答道歉!事实证明你是完全正确的。我总是使用[unowned self]
来处理这种情况。
你为什么不使用[weak self]
,因为你发现它没有问题?
是的,可以做到。但我最终还是使用了strongSelf
以获得更好的可读性。
【参考方案1】:
即使您有一个强引用循环,您也不会看到任何内存泄漏,直到所有其他强引用消失。
例如,如果这个 VC 在整个应用程序生命周期内都处于活动状态,即使闭包捕获了一个强引用循环,它也不会做任何事情。影响将是相同的:VC 将在整个应用程序生命周期内都处于活动状态,无论如何它已经在这样做了。
只有当你有一个强引用循环时,你才能识别内存泄漏,然后尝试通过删除所有其他强引用来取消初始化 VC。
【讨论】:
VC 在应用程序的整个生命周期内都不会存在,我希望在 VC 代表的屏幕关闭后释放 VC 及其模型控制器。我对上述代码没有任何保留问题。我正在寻找在嵌套更改处理程序中访问 self 的最佳方法。我应该在嵌套块中将 self 称为“self”,还是应该引用在父块的捕获列表中声明的 self(strongSelf) 的较弱版本。 @SwiftTechnocrat 因此,当您关闭该 VC 的屏幕时,您应该会在 Instruments 中看到内存泄漏。 是的,我确实看到了内存泄漏,并且当我没有在父块中声明 self 为弱时,deinit 永远不会执行。 @SwiftTechnocrat 是的,这是有道理的。我想我不明白你的问题,你在问什么?在nest scoped中,你要弱捕获self
,同理。
是的,应该弱弱地捕获自我。在这种情况下,它是否被称为self
或self
的弱版本(即strongSelf
)并不重要。从技术上讲,两者是相同的。我的印象是使用嵌套块中的self
捕获列表可能会导致保留周期。感谢您的投入。以上是关于Swift:嵌套闭包中的自引用的主要内容,如果未能解决你的问题,请参考以下文章