Iphone 块中对自身的引用较弱,有时会导致错误的_过量

Iphone 块中对自身的引用较弱,有时会导致错误的_过量,iphone,objective-c,automatic-ref-counting,objective-c-blocks,Iphone,Objective C,Automatic Ref Counting,Objective C Blocks,我有一个对象,它使用委托块。我用的是ARC @implementation ViewController - (void)createGame { _game = [[MRCircusGame alloc] init]; _game.mainView = self.view; _game.stageObjectsDictionary = [self getStageObjectsDictionary]; [_game prepareGame]; } - (NS

我有一个对象,它使用委托块。我用的是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;
}


一些问题:

若我不使用self的弱引用,Xcode会对可能的保留周期发出一些警告。但我查看了一下仪器,即使我使用
self.isAnimating=YES,也没有发现内存泄漏

如果我不使用这个strongRef解决方案,有时我会得到坏的\u过量,所以我认为它是弱的\u self被释放了,对吗?我应该一直使用strongRef来防止我的应用程序崩溃吗


此块执行结束时是否会释放strongRef?

正确的方法是直接访问实例变量:

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

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

self.animator.didEndAnimating = nil;

我以前也遇到过类似的问题。出现此问题的主要原因是,在动画结束之前对象被解除分配。因此,当执行块时,引用的“self”不在那里

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

  • 重写“dealoc”方法,然后将nil指定给self.animator.didEndAnimating。因此,动画之后不会执行任何操作

  • 在块中,您可以检查“self”是否为零,然后执行您想要的操作


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

    仪器仅在以下情况下显示无法到达的对象:

    • 在块内使用self的强引用
    • 你不需要在dealloc中取消对块的引用
    • 你没有提到强人

    animator是StrongMan super Classes的财产animator没有问题,但执行程序中的代码是有问题的block@mundi那有什么关系?真正的好奇是不需要的,因为当自我消失时,弱者将被消灭,不?1会起作用,2我不明白。。但同样地,AFAICS这不应该是必要的——弱变量为零,否?1)我真的需要在动画完成后执行整个块。2) 也许它会起作用,但从一开始就对弱自我进行强引用并不是更好吗?@alexhajdu那么在这种情况下,问题是对象的释放。你怎么保存那个东西?我认为,在这种情况下,我们讨论的是“视图”,因此,如果将视图指定给视图控制器的强变量,就我所知,问题可以得到解决。“问题的主要原因是,对象在动画结束前被解除分配。因此,当执行块时,引用的“自我”不存在。”因此,参考值将为
    nil
    。“这为什么会导致OP的问题?”ÖmerFarukGül更新了问题。您现在可以看到我是如何创建对象的。或者我应该只使用self而不关心警告?有三种方法可以打破循环:1)范围:复制变量,这样您就不需要引用self。2) 以编程方式:nil导致保留循环的块属性。3) 属性:使用弱引用。不能使用1),因为需要设置self的属性,但可以选择使用2或3。我更喜欢3)这样我以后就不必记得什么都不做了。1)你能解释一下吗?2) 即使我需要执行此块,我也可以不执行吗?3) 为什么使用弱引用?1)如果你在你的块中需要self.age,你可以使用整数nsux=self.age;在创建副本的方法中,引用堆栈变量(x),而不是ivar(self.age)。这样就不需要使用self。您不能在代码中这样做,因为您正在设置ivar(isAnimating)2)否,不需要,因为您已经在使用弱引用来避免循环。3) 弱引用引用self,正如您在代码中所做的那样。不可能从您显示的代码中获得EXEC\u BAD\u访问权限。是,如果在块触发之前解除分配了
    self
    ,则
    weak\u self
    将是
    nil
    ,并且
    strongRef
    也将是。但是您只是在
    strongRef
    上调用方法,而在Objective-C中调用
    nil
    上的方法是可以的。您肯定在其他地方遇到了问题。此外,您显示的图像与代码不匹配。这是哪一个?在区块内的参考不应该是弱自我而不是自我吗?(图中)
    _animator.didEndAnimating = ^{ .... };
    
    self.animator.didEndAnimating = nil;