Remove shadowing of variables
JonasGessner opened this issue · 10 comments
These declarations are not repeats, although I agree the naming is confusing. The initial weakSelf is to avoid a retain cycle, but to actually use it safely in the block we need to make a strong reference first (otherwise it's possible for weakSelf to be deallocated mid-function from another thread.) The second weakSelf does exactly the same thing, except this time for the inner block, and then we need to make another strong reference for the same reason. In the example you highlight I actually skipped the final nil check since we're only calling one method and it's safe for strongSelf to be nil.
The weak/strong dance is ugly but it's functionally necessary. If you have a suggestion to make it more concise I'd love to hear it!
@jstn by default now, the warning for shadow declarations is enabled. While the code right now is functionally correct, it would be nice if it didn't use shadow declarations, if only to silence the warning.
Interesting, I didn't know that. So it has to be even uglier : (
h8 u apple
I am totally aware of the use of the weakSelf/strongSelf pattern. But I would change a few things:
• Declaring weakSelf twice is unnecessary. The initial weakSelf is sufficient and declaring another weak reference to self is redundant.
• In the case of strongSelf, where it really is necessary to declare it twice I would change the name of the second strongSelf. Simply call it strongSelf_ and all warnings will be gone. It will also make the code cleaner because you will immediately be able to see "which" of the declared strongSelf variables is accessed.
• Or, instead of declaring strongSelf again, don't declare it again but assign the new value to the existing variable.
I would also recommend to use these macros to make things easier:
#define weakSelfMake __weak __typeof(self) weakSelf = self
#define strongSelfMake __strong __typeof(weakSelf) strongSelf = weakSelf
I disagree that it's unnecessary, but I've made my case, it's up to Mr Geddins now. The rest is just a matter of style.
I don't know if weak references are needed at all in most of these cases. I'm pretty sure it's fine to refer to self
in a block passed to dispatch_sync
or dispatch_async
, even when the queue that the blocks are being added to is retained by self
. The queue releases the block once it executes, meaning you won't end up with a retain cycle.
@irace is, of course, correct -- presuming the dispatch queue flushes. Retaining self
will, however, ensure that the block will be run, which, I believe, is the intended behavior.
Retaining self will, however, ensure that the block will be run, which, I believe, is the intended behavior.
@segiddins This would be another argument (the first being the stylistic one) for not using weak references at all, correct?
Yes.