ARC: weakSelf Caveats

Here’s an interesting ARC scenario. Consider the following snippet:

[cc lang=”objc”]
__weak __typeof(self) weakSelf = self;
int64_t delay = (int64_t)(0.1 * NSEC_PER_SEC);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay), dispatch_get_main_queue(), ^{
[weakSelf doSomething];
});
[/cc]

Whenever the block gets executed… weakSelf might have a valid reference, or not. Right?.
Now, what happens with the following snippet?

[cc lang=”objc”]
__weak __typeof(self) weakSelf = self;
int64_t delay = (int64_t)(0.1 * NSEC_PER_SEC);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay), dispatch_get_main_queue(), ^{
[weakSelf doSomething];
[weakSelf doSomethingElse];
});
[/cc]

This is where it gets interesting!. There’s a possibility that doSomething might get executed, while doSomethingElse might not.

If you need to prevent such scenario, a possible workaround is:

[cc lang=”objc”]
__weak __typeof(self) weakSelf = self;
int64_t delay = (int64_t)(0.1 * NSEC_PER_SEC);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay), dispatch_get_main_queue(), ^{
__typeof(self) strongSelf = weakSelf;
[strongSelf doSomething];
[strongSelf doSomethingElse];
});
[/cc]

This snippet warrantees that: if (at the moment of the block’s execution) weakSelf is not nil, it won’t be for the rest of the snippet.

Another interesting note (for future reference) is: self is considered strong, and it may not get invalidated at the middle of a method execution. Okay?

P.s.: Thanks to this Blog Post