When we use the weak
modifier before either self
or some property (reference type, not struct) of self in a capture list we create a new local variable having the same name as the captured type but being weak. This is a bit odd. The resulting code is really confusing if you want to use good variables names. Have a look at the code in RxSwift extenison doing the weakify, strongify dance:
func weakify<A: AnyObject, B>(_ obj: A, method: ((A) -> (B) -> Void)?) -> ((B) -> Void) {
return { [weak obj] value in
guard let obj = obj else { return }
method?(obj)(value)
}
}
The naming of the object is just obj
, which is not so swifty. When we attempt to replace obj
more descriptive names we see that it easily gets MORE confusing:
func weakify<A: AnyObject, B>(_ strongObject: A, method: ((A) -> (B) -> Void)?) -> ((B) -> Void) {
return { [weak strongObject] value in // strongObject is actually now weak, thanks to the `weak` in the capture list
let weakObject: A? = strongObject // correcting the confusing name `strongObject`, which actually is weak
guard let strongAgain = weakObject else { return } // we have now strongified the weakified initial object
method?(strongAgain)(value)
}
}
If we could weakify and also rename the captured type as an action we could get more easily read code:
func weakify<A: AnyObject, B>(_ strongObject: A, method: ((A) -> (B) -> Void)?) -> ((B) -> Void) {
return { [weak strongObject -> weakObject] value in
guard let object = weakObject else { return }
method?(object)(value)
}
}
What do you say?