retain cycle
seanliu1 opened this issue · 3 comments
loadSomething().then { something in
self.loadAnother(with: something)
}
func loadAnother(with something: Data) -> Promise<MyResult> {
loadAnother().then { another in
self.doSomething(with: something, and: another)
}
}
This is piece of code from readme.
Do we need to use [weak self]?
Hi @seanliu1,
That code can be rewritten in the following way using GCD (let's ignore error handling), if that makes ownership clearer:
func loadSomething(_ completion: (Data) -> Void) {
DispatchQueue.global().async {
let something = MyLoader.syncLoadSomething()
DispatchQueue.main.async {
completion(something)
}
}
}
loadSomething { something in
self.loadAnother(with: something) { result in
// use result
}
}
func loadAnother(with something: Data, _ completion: (MyResult) -> Void) {
loadAnother { another in
self.doSomething(with: something, and: another) { result in
completion(result)
}
}
}
As you see, self
gets captured by GCD at every completion handler.
So the answer whether to make it weak is "maybe" :)
It depends on whether you want self
stay alive until all the async calls are completed, or you prefer to let it go earlier.
Thanks.
Thanks for your detailed explanation. Yes, if we want weak self. What is the best way to do it. Do we create another error type for weak self, or we just return optional Promise. or we just fulfill with nil. Based on the best practice we should always fulfill or reject. If we use optional, when we chain them, it is not convenient at all. So I am curious what is the best practice for doing it?
Again, it really depends.
If you capture a weak self
, it's up to you how you're going to convey to the caller that self
got deallocated. May throw
an Error
, or resolve with an empty result, or a Void
, or just have an Optional
result. I imagine the latter is probably the easiest in terms of code refactoring:
func loadAnother(with something: Data) -> Promise<MyResult?> {
loadAnother().then { [weak self] another in
self?.doSomething(with: something, and: another)
}
}