I’m wondering is the variable declaration from the question topic is legitimate. Imagine the following code:
__weak typeof(self) weakSelf = self;
[self doSomethingThatMayCauseRetainCycleWithBlock:^{
typeof(self) self = weakSelf; // <---- !!!!
if (self == nil) return;
NSAssert(self.someProperty != nil, @"This doesn't lead to retain cycle!");
[self doSomething];
self.someProperty = someValue;
// even
self->someIvar = anotherValue;
}
This code works perfectly in Xcode 4.5.2, only giving a warning that Declaration shadows a local variable.
What’s the point of this quirk:
- Having redeclared
selfas a strong reference to a weak variable, you can safely copy/move code inside/outside the block without a risk to occasionally create a retain cycle (except for ivars, but they are evil). NSAssertin a block doesn’t cause retain cycle anymore.
Update
I discovered that this technique is used in libextobjc for @weakify/@strongify macros.
Strictly speaking, there is nothing wrong with your code — the variable declaration is legitimate. However, you will probably get a compiler warning about the local variable shadowing the instance one.
GCD blocks are actually C functions, not Objective-C methods. When compiled, every Objective-C instance method has an extra parameter added to it, which is the
selfpointer.selfisn’t stored in the object struct like other variables.For this reason, I would hesitate to use this code in a library I was going to share. The code may break with newer versions of then compiler because you’re actually hacking the runtime a little more than is immediately apparent. Additionally, it’s quirky code, as you point out 🙂 I’m not sure that anyone else reading it would immediately understand what’s going on.