I have a class A
that stores a optional weak variable
to other object, that is a subclass
of A
. Sometimes when I store something in this variable I get a leak
- this happens rarely, but it does. I'm assigning this variable in forEach loop
, but I also found similar leak in other place of application once when using weak var
, so I don't think that loop has anything to do with this. Responsible library is libswiftCore.dylib
and responsible frame is swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1> >::formWeakReference()
. Did someone else have had similar issue? Is there some way I can fix this?
Try setting the variable instead of being weak
set it to be unowned
.
This is a Swift bug sort of as there is no warning for the developer that he is capturing a strong reference of the nested closure, however, setting it to unowned
should do as a workaround for now.
EDIT1: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001197.html
Mentioned as an improvement from here here:
class ViewControllerBase: UIViewController {
let timer:DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue(label: "q.q"))
deinit {
NSLog("deinit of \(NSStringFromClass(type(of: self)))")
}
override func viewDidLoad() {
super.viewDidLoad()
timer.scheduleRepeating(deadline: .now(), interval: .seconds(1))
timer.setEventHandler {
UIView.animate(withDuration: 0.2) { [weak self] in
self?.view.backgroundColor = UIColor.green
}
}
}
This leaks memory in a subtle way...there is a retain loop even though self is only used in a "weak" manner. This is because the nested closure captures a strong reference for use in the closure that follows.
EDIT 2:
I might be wrong but the OP is using changes.forEach
closure and then another closure with changes.added.forEach
I could be wrong but this might be the cause of the whole issue perhaps declaring it there [weak self] (cluster, change)
in ... could possibly remove the issue. It is swifts built in closure but still a closure, that could technically cause them to be nested.
Try changing your code to:
changes.forEach{[weak self] (cluster, change) in
see if that helps
or
changes.forEach{[unowned self] (cluster, change) in
Also any chance that you could paste your code instead of doing a screenshot as it is easier to recreate your code instead of retyping it.
unowned
and weak
have different meaning - weak
is by definition optional and must be unwrapped (safely or not) before use, we can safely check it for nil (since it is optional). unowned
can't be optional, thus it is inapplicable in cases where I need to use weak
(and check for nil). As for "this is bug" - could you cite any authoritative source? –
Hezekiah weak var
(like question author) and it still produces leak. –
Hezekiah © 2022 - 2024 — McMap. All rights reserved.
Unmanaged<T>
but decided to revert the fix in favor of more readable code. FYI, in my case, the actual object that I was storing in a weak property wasn't being retained so not fixing the issue was OK for me. – Perrault