阻止CGFloat ivars的自我保留?

时间:2019-01-05 14:40:23

标签: objective-c objective-c-blocks ivar

我有一个带有这样的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行显示此错误:

  

块隐式保留了“自我”;明确提及“自我”以表示   这是故意的行为

我知道如何解决此属性,但是CGFloat ivars又如何呢?

2 个答案:

答案 0 :(得分:3)

语法为self->minimumForegroundWidth。箭头而不是点。可以回溯到self实际上是指向struct的指针,而->是引用该成员的C符号。

答案 1 :(得分:2)

  

我知道如何解决此属性,但是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模式在可能存在较强参考周期的地方非常重要(例如,您将代码块保存在属性中,将其用于重复计时器等)。