Блокировать сохранение себя для CGFloat ivars?
У меня есть класс с иваром, как это:
@interface MCProgressBarView() {
CGFloat minimumForegroundWidth;
CGFloat availableWidth;
}
позже в коде у меня есть это:
dispatch_async(dispatch_get_main_queue(), ^{
CGRect frame = _foregroundImageView.frame;
frame.size.width = roundf(minimumForegroundWidth + availableWidth * valor);
_foregroundImageView.frame = frame;
[self layoutIfNeeded];
});
minimumForegroundWidth
строка этого более позднего кода показывает эту ошибку:
Блок неявно сохраняет "я"; явно указать "я", чтобы указать, что это предполагаемое поведение
Я знаю, как решить эту проблему для свойств, но как насчет CGFloat ivars?
2 ответа
Синтаксис self->minimumForegroundWidth
, Стрелка, а не точка. Это возвращается к тому факту, что self
на самом деле указатель на структуру, и ->
это нотация C для ссылки на членов этого.
Я знаю, как решить это для свойств, но как насчет
CGFloat
Ивар
Как вы знаете, решение для свойств weakSelf
шаблон:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
CGFloat localVar = weakSelf.property;
...
});
Решение для ivars очень похоже, за исключением того, что вам нужно явно проверить, weakSelf
является nil
или нет, потому что вы не можете разыменовать ивар из nil
указатель. Таким образом, вы создаете сильную местную ссылку на ваш weakSelf
а затем проверьте, если это не nil
:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
typeof(self) strongSelf = weakSelf;
if (strongSelf) {
CGFloat localVar = strongSelf->ivar;
}
});
Очевидно, что в вашем примере мы, как правило, не будем беспокоиться о сильных ссылочных циклах (поскольку цикл разрешается сразу после завершения блока), а просто используем self->minimumForegroundWidth
синтаксис, чтобы заставить замолчать предупреждение. Но выше weakSelf
шаблоны важны там, где возможны сильные ссылочные циклы (например, вы сохраняете блок в свойстве, используете его для повторения таймера и т. д.).