阻止 CGFloat ivars 保留自我?
Block retaining self for CGFloat ivars?
我有一个 class 和这样的 ivar:
@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
行显示此错误:
Block implicitly retains 'self'; explicitly mention 'self' to indicate
this is intended behavior
我知道如何为属性解决这个问题,但是 CGFloat ivars 呢?
语法为self->minimumForegroundWidth
。箭头而不是点。这要追溯到 self
实际上是一个指向结构的指针,而 ->
是引用结构成员的 C 表示法。
I know how to solve this for properties but what about CGFloat
ivars
如您所知,属性的解决方案是 weakSelf
模式:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
CGFloat localVar = weakSelf.property;
...
});
ivars 的解决方案非常相似,只是您需要明确检查 weakSelf
是否为 nil
,因为您无法从 nil
指针中取消引用 ivar。因此,您创建了对 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
模式在可能存在强引用循环的情况下很重要(例如,您将块保存在 属性 中,将其用于重复计时器等)。
我有一个 class 和这样的 ivar:
@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
行显示此错误:
Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior
我知道如何为属性解决这个问题,但是 CGFloat ivars 呢?
语法为self->minimumForegroundWidth
。箭头而不是点。这要追溯到 self
实际上是一个指向结构的指针,而 ->
是引用结构成员的 C 表示法。
I know how to solve this for properties but what about
CGFloat
ivars
如您所知,属性的解决方案是 weakSelf
模式:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
CGFloat localVar = weakSelf.property;
...
});
ivars 的解决方案非常相似,只是您需要明确检查 weakSelf
是否为 nil
,因为您无法从 nil
指针中取消引用 ivar。因此,您创建了对 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
模式在可能存在强引用循环的情况下很重要(例如,您将块保存在 属性 中,将其用于重复计时器等)。