0

我对按钮有以下操作,它可以切换对象是显示为收藏还是非收藏:

- (IBAction)addToFavorites:(UIButton *)sender {
  if ([object isFavorite]) {
    [_apiManager removeFromFavorite:[object ID] withCompletion:^ {
      [_favoriteButton setImage:[UIImage imageNamed:@"favorite"] forState:UIControlStateNormal];
    }];
  }

  else {
    [_apiManager addToFavorite:[object ID] withCompletion:^ {
      [_favoriteButton setImage:[UIImage imageNamed:@"favorite_yellow"] forState:UIControlStateNormal];
    }];
  }
}

两个完成块是相同的,除了图像名称。XCode 向else案例发出警告:Capturing 'self' strongly in this block is likely to lead to a retain cycle并指向_favoriteButton. if但是,在条件为真的情况下不会发生同样的情况。

我想这两种情况或都不应该出现警告,我不明白为什么只有后者才显示它。这是一个 Xcode 错误吗?两者都导致保留周期吗?

4

2 回答 2

3

_favoriteButton是一个伊瓦尔。它由您的类的特定实例拥有,因此使用它可以捕获self块中的当前(引用块内的实例变量

相反,您应该创建对 self 的弱引用,并使用属性访问器,如下所示:

- (IBAction)addToFavorites:(UIButton *)sender {
  __weak YourViewControllerClass *weakSelf = self;
  if ([object isFavorite]) {
    [_apiManager removeFromFavorite:[object ID] withCompletion:^ {
      [weakSelf.favoriteButton setImage:[UIImage imageNamed:@"favorite"] forState:UIControlStateNormal];
    }];
  }

  else {
    [_apiManager addToFavorite:[object ID] withCompletion:^ {
      [weakSelf.favoriteButton setImage:[UIImage imageNamed:@"favorite_yellow"] forState:UIControlStateNormal];
    }];
  }
}
于 2013-10-09T13:52:11.040 回答
0

实际上,在此示例中并不清楚是否存在保留周期。如果完成块被声明为_apiManager. 如果它只是方法范围的一个块(只是一个方法参数),那么就没有保留周期,但是 XCode 不够聪明,无法检测这些情况并警告您可能存在保留周期。

关于您的问题,这只是顺序,它会在第一个保留周期中警告您,第二个无关紧要,因为该块已经从第一个块中保留了自己。如果您使用__weakself 修复第一个警告,它将在第二个块上发出警告。

于 2016-08-12T10:33:36.093 回答