What’s the correct way to reference ‘self’ (and ivars) within blocks without the block creating a strong reference (and thus incrementing the ref count)?
For instance, I’ve found the following increments the ref count for ‘self’:
^(id sender) {
[self.navigationController popViewControllerAnimated:YES];
}
In order to circumvent the above, I’ve been doing the following:
__weak WhateverController *weakSelf = self;
^(id sender) {
[weakSelf.navigationController popViewControllerAnimated:YES];
};
And yes, I realize this is pseudocode.
Also, an indirect reference to self also creates a retain on self. For example, if
_ivarwere an instance variable, accessing it is an implicit reference to self so the following would also retain self.Furthermore, to expand on your
weakexample, it is OK to send a message to a weak reference. If it’s nil, nothing will happen. If not, then the compiler will generate code that ensures the reference remains valid through the invocation of the method.So, this is fine:
because foo will either be
nilor if not, it is guaranteed to remain non-nil throughout the execution ofdoSomething.However, the following would be inadvisable because
selfcould go tonilin-between calls, which is probably not what you want:In that case, you probably want to create your own strong reference inside the block, so you have a consistent value throughout the execution of the block.
On the other hand, if you access iVars directly through a weak reference, you must do the weak-strong dance because this code:
will blow up if
weakSelfisnil.Thus, in the last two situations above, you want to do something like:
Of course, the iVar situation is only a problem if you actually access iVars directly…