【发布时间】:2013-03-18 21:45:11
【问题描述】:
我真的被这个难住了。我一直在阅读有关如何正确处理块内变量的所有信息。
注意:我没有使用 arc。
所以,假设我有一个看起来像这样的动画:
[UIView animateWithDuration:.5 animations:^{
textCard.alpha = 1.f;
self.dotView.alpha = 1.f;
self.subtitles.alpha = 0;
}completion:^(BOOL finished){
[self.playerLayer removeFromSuperlayer];
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.vidPlayer];
self.playerLayer.frame = self.vidView.bounds;
[self.vidView.layer insertSublayer:self.playerLayer atIndex:0];
[self.subtitles removeFromSuperview];
self.subtitles = [sub autorelease];
[UIView animateWithDuration:.3 delay:1 options:UIViewAnimationOptionAllowUserInteraction animations:^{
textCard.alpha = 0.f;
sub.alpha = 1.f;
}completion:^(BOOL finished){
self.queuedVid = NO;
if (self.shouldPlay == YES) {
[self.vidPlayer play];
[self setCurrentVideoSettings];
}
else{
self.shouldPlay = YES;
}
[textCard removeFromSuperview];
textCard = nil;
}];
}];
现在这段代码可能看起来有点随意,但这是我必须做的一个非常真实的例子。
这是我的两个问题:
如果我保持原样,并且在调用此块期间(尝试)释放类,它将不会释放。
如果我将 self 更改为
__block typeof (self) weakRef = self;,那么如果类在第二个块可以运行之前被释放,它会崩溃,因为它试图引用我释放的 self。
我知道我一定不明白这是如何工作的,但如果有人能解释一下,我将不胜感激。
【问题讨论】:
-
你的两个问题不兼容。动画块延长了
self的生命周期,或者self在中间死亡,动画块开始引用垃圾对象。第一个“问题”通常被认为是一个特性。 -
@KevinBallard 延长寿命就好了。但不能完全阻止它解除分配。我不确定您所说的“垃圾对象”是什么意思,因为我没有使用弧。它只是崩溃。我需要某种方式来取消块调用,或者......我需要我的变量在尝试调用时以某种方式返回 nil,以避免崩溃。
-
它不会阻止对象被释放。一旦完成块被触发,它就会删除对
self的引用,从而释放它。如果您看到对象 never 被释放,那么您还有其他事情发生。 -
“垃圾对象”表示对象“self”是指向内存位置的指针。当对象被释放时,该内存位置可能会被任意数据覆盖,即。垃圾。
-
@KevinBallard 我不明白积木是如何工作的。现在这对我来说很有意义。所以问题是在延迟调用中我告诉我的电影播放器播放。我解决了这个问题,现在我的班级在块完成后立即解除分配。
标签: ios objective-c memory-management objective-c-blocks uiviewanimation