Reputation: 35933
I have a class with an ivar like this:
@interface MCProgressBarView() {
CGFloat minimumForegroundWidth;
CGFloat availableWidth;
}
later in code, I have this:
dispatch_async(dispatch_get_main_queue(), ^{
CGRect frame = _foregroundImageView.frame;
frame.size.width = roundf(minimumForegroundWidth + availableWidth * valor);
_foregroundImageView.frame = frame;
[self layoutIfNeeded];
});
The minimumForegroundWidth
line of this later code shows this error:
Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior
I know how to solve this for properties but what about CGFloat ivars?
Upvotes: 2
Views: 60
Reputation: 437381
I know how to solve this for properties but what about
CGFloat
ivars
As you know, the solution for properties is weakSelf
pattern:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
CGFloat localVar = weakSelf.property;
...
});
The solution for ivars is very similar except you need to explicitly check to see if weakSelf
is nil
or not, because you cannot dereference an ivar from nil
pointer. So you create a strong local reference to your weakSelf
and then check to see if it’s not nil
:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
typeof(self) strongSelf = weakSelf;
if (strongSelf) {
CGFloat localVar = strongSelf->ivar;
}
});
Obviously, in your example, we generally wouldn’t worry about strong reference cycles (because the cycle is resolved as soon as the block finishes) and just use self->minimumForegroundWidth
syntax to silence the warning. But the above weakSelf
patterns are important where strong reference cycles are possible (e.g., you’re saving the block in a property, using it for repeating timer, etc.).
Upvotes: 2
Reputation: 299265
The syntax is self->minimumForegroundWidth
. Arrow rather than dot. It's going back to the fact that self
is actually a pointer to struct, and ->
is the the C notation for referencing members of that.
Upvotes: 3