ARC: weakSelf Caveats

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

__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];
});

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

__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];
});

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:

__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];
});

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