在块中对self的弱引用有时会导致BAD_EXCESS

时间:2013-04-28 12:50:52

标签: iphone objective-c automatic-ref-counting objective-c-blocks

enter image description here我反对,它正在使用委托块。我正在使用ARC。

@implementation ViewController

- (void)createGame
{
    _game = [[MRCircusGame alloc] init];
    _game.mainView = self.view;
    _game.stageObjectsDictionary = [self getStageObjectsDictionary];
    [_game prepareGame];
}

- (NSMutableDictionary *)getStageObjectsDictionary
{
    StrongMan *strongMan = [[StrongMan alloc] initAndCreateImageViewWithFrame:kStrongManIntroFrame inView:self.view];
    strongMan.isTakingTouches = NO;
    strongMan.isVisible = NO;
    [tempDictionary setObject:strongMan forKey:kMRCircusStrongMan];
    return tempDictionary;
}

@interface MRCircusGame
{
@property (nonatomic, strong) NSMutableDictionary *stageObjectsDictionary;
}

@implementation StrongMan
..
-(void)method
{
  __weak typeof (self) weak_self = self;
  self.animator.didEndAnimating = ^{
            StrongMan *strongRef = weak_self;
            strongRef.isAnimating = NO;
            [strongRef idle];
  };  
}

有些问题:

如果我不使用弱引用自我,Xcode会对可能的保留周期发出警告。但我查看了仪器,即使使用self.isAnimating = YES;

,也没有检测到任何密封泄漏

如果我不使用这个strongRef解决方法,有时候我得到了BAD_EXCESS,所以我觉得它发布了weak_self,我是对的吗?我应该一直使用strongRef来阻止我的应用程序崩溃吗?

当此块执行结束时,strongRef会被释放吗?

4 个答案:

答案 0 :(得分:2)

强烈引用弱引用是在块运行时保持自身活动的常用技术。在块结束时,strongRef将被释放。

如果

,仪器将只显示无法访问的对象
  • 你在街区内使用强烈的自我引用
  • 并且你没有在dealloc
  • 中对块的引用
  • 你没有提到StrongMan

答案 1 :(得分:1)

之前我遇到过类似的问题。问题的主要原因是,在动画结束之前对象被释放。因此,当执行块时,引用的“self”不存在。

我认为这个问题有两个解决方案:

  1. 您覆盖“dealloc”方法,然后将nil分配给self.animator.didEndAnimating。因此在动画之后不执行任何操作。

  2. 在街区,您可以查看天气“自我”是否为零,然后按照自己的意愿行事。

答案 2 :(得分:0)

如果使用弱引用并且在动画停止之前释放StrongMan的实例,则应用程序将崩溃。为了防止崩溃,您应该在释放对象时删除引用。在dealloc方法中使用以下代码应该这样做:

self.animator.didEndAnimating = nil;

答案 3 :(得分:-1)

执行此操作的正确方法是直接访问实例变量:

_animator.didEndAnimating = ^{ .... };