iphone - block 中对 self 的弱引用有时会导致 BAD_EXCESS

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

enter image description here我反对,它正在使用委托(delegate) block 。我正在使用 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];
  };  
}

一些问题:

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

也没有检测到内存泄漏。

如果我不使用这个strongRef解决方法,有时我会得到BAD_EXCESS,所以我认为weak_self已被释放,对吗?我应该一直使用 StrongRef 来防止我的应用程序崩溃吗?

当该 block 执行结束时,strongRef 会被释放吗?

最佳答案

对弱引用进行强引用是在 block 运行时保持自身存活的常用技术。在 block 结束时,strongRef 将被释放。

只有在以下情况下仪器才会显示无法访问的对象

  • 您在 block 内使用了对 self 的强引用
  • 并且您不会在 dealloc 中清零对 block 的引用
  • 并且您取消了对 StrongMan 的引用

关于iphone - block 中对 self 的弱引用有时会导致 BAD_EXCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16263052/

相关文章:

iphone - 调试 iPhone 应用程序

iphone - 使用 dequeueReusableCellWithIdentifier 会导致用作重复背景的图像泄漏出单元格

ios - 将图像缩放到给定的NSData字节大小-PNG压缩

ios - UIView 的 subview 或组件不随 View 移动

iPhone 与 CorePlot 的多点触控交互

iphone - 创建一个 NSError 域

objective-c - 在 init 方法中调用 self 中的 init 方法可以吗?

ios - @property definitions with ARC : strong is the default value, 但基本类型的默认值是多少?

iphone - 为什么我们在 iOS 中需要 property outlet 和 variable?

ios - (iOS) 使用 goto 时跳转绕过保留变量的初始化