问题描述
我试图掌握如何识别强保留周期,并要求我使用[weak/unowned self]
.我已经被不必要地使用[weak/unowned self]
烧死了,并且在我有机会使用它之前立即将自身释放了.
I am trying to grasp how I can recognize when a strong retain cycle is possible and requires me to use [weak/unowned self]
. I've been burned by unnecessarily using [weak/unowned self]
and the self was deallocated immediately before giving me a chance to use it.
例如,下面是一个异步网络调用,该调用在闭包中引用了self
.因为进行网络调用而没有将其自身存储到变量中,所以这里会发生内存泄漏吗?
For example, below is an async network call that refers to self
in the closure. Can a memory leak happen here since the network call is made without storing the call it self into a variable?
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) {
(data, response, error) in
self.data = data
)
这是使用NSNotificationCenter的另一个示例,稍后可以异步进行调用:
Here's another example using the NSNotificationCenter, where a call can be made later asynchronously:
NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationSignificantTimeChangeNotification, object: nil, queue: nil) {
[unowned self] _ in
self.refresh()
}
我的问题是,在什么情况下可能会发生强大的保留周期?如果我要在闭包中进行引用self的异步调用或静态调用,是否会使它成为[weak/unowned self]
的候选对象?感谢您对此发表意见.
My question is in what cases is a strong retain cycle possible? If I am making an asynchronous call or static call that references self in a closure, does that make it a candidate for [weak/unowned self]
? Thanks for shedding any light on this.
推荐答案
简而言之:
保留周期可以在两种情况下发生.
The retain cycle can happen in two cases.
案例1:
当两个实例相互引用很强时.您必须通过将其中一个标记为弱来解决此问题.
When two instances hold a strong reference to each other. You have to solve this by marking one of them as weak.
案例2 :(与您的问题有关)
如果将闭包分配给类实例的属性,并且该闭包的主体捕获该实例.
If you assign a closure to a property of a class instance and the body of that closure captures the instance.
在您的两个示例中,根本不需要使用弱自我,因为NSNotificationCenter
和NSURLSession
是类实例的属性. (或者换句话说,您没有对它们的强烈引用)
In your two examples, no need to use weak self at all as NSNotificationCenter
nor NSURLSession
are properties to your class instance. (Or in other meaning, you don't have strong references to them)
在需要使用弱自我的情况下查看此示例:
Check this example where I have to use weak self:
[self.mm_drawerController setDrawerVisualStateBlock:^(MMDrawerController *drawerController, MMDrawerSide drawerSide, CGFloat percentVisible) {
if (drawerSide == MMDrawerSideRight && percentVisible == 1.0) {
[weakself showOverlayBgWithCloseButton:YES];
}
else{
[weakself hideOverlayBg];
}
}];
我对mm_drawerController
有很强的引用,因此给它分配了一个闭包,对吗?在这个封闭中,我想捕捉自我.因此,关闭将对自我有强烈的参考!这是一场灾难.在这种情况下,您将有一个保留周期.要打破此循环,请在闭包内部使用弱self.
I have a strong reference to mm_drawerController
and I assign a closure to it right?. inside this closure I want to capture self. So the closure will have a strong reference to self !! which is a disaster. In that case you will have a retain cycle. To break this cycle, use weak self inside the closure.
这篇关于异步或静态调用如何实现强大的保留周期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!