I've been wondering if unwrapping weak self within the escaping closure's scope brings some benefits other than aesthetical ones? Consider those two examples:
When we unwrap self:
func test() {
Test.closureFunction { [weak self] parameter in
guard let self = self else { return }
self.someFunction(parameter)
}
}
When we don't unwrap self:
func test() {
Test.closureFunction { [weak self] parameter in
self?.someFunction(parameter)
}
}
Could there be a scenario when not unwrapped self (1st example) may become nil as a result of some other asynchronous operation, thus the execution of the scope may differ from when we unwrap self (2nd example)? I believe it's a possible scenario, but I may be wrong.
I think that we may still want to execute an operation from within the escaping closure's scope while self is already nil. After this escaping closure finishes its scope the unwrapped self is released.
Thank you
2条答案
按热度按时间zwghvu4y1#
The answer is "it depends."
If you use a
guard let
, your closure captures self at the beginning of the closure. Self will not get released until your closure has finished running. Also, you won't need to unwrap it each time you use it (The "aesthetic" part)In most cases, this makes sense, since once you start doing work in your closure, you likely want to do all that work.
If you don't use a
guard let
, your instance of self could get released in the middle of your closure's execution.If the owner of your object (whoever is keeping a strong reference to self) might release the object while your closure is running and that means there is no point in continuing (which will depend on your use-case) then don't use a
guard let
and instead keep unwrapping, and/or keep checking to see if self is nil, and returning if it is nil.zwghvu4y2#
邓肯C很好地解释了这些问题,但我认为一个简单的例子就能说明问题:
关键的一点是,在这两种情况下,代码都是“安全的”。(在没有未定义的行为/不安全的代码或Swift bug的情况下)
self
不可能是一个悬空指针,也不可能改变它所指向的对象。