2012-10-08 55 views
2

我想了解自动引用计数,因为我来自高级编程语言(Python),而且我正在使用Objective-C的这一特性的项目。我经常遇到ARC解除分配我以后需要的对象的问题,但现在我有一个具体的例子,我希望我能得到一个解释。为什么我的NSArray被释放?

- (void) animateGun:(UIImageView *)gun withFilmStrip:(UIImage *)filmstrip{ 
    NSMutableArray *frames = [[NSMutableArray alloc] init]; 
    NSInteger framesno = filmstrip.size.width/gun_width; 
    for (int x=0; x<framesno; x++){ 
    CGImageRef cFrame = CGImageCreateWithImageInRect(filmstrip.CGImage, CGRectMake(x * gun_width, 0, gun_width, gun_height)); 
    [frames addObject:[UIImage imageWithCGImage:cFrame]]; 
    CGImageRelease(cFrame); 
    } 
    gun.image = [frames objectAtIndex:0]; 
    gun.animationImages = frames; 
    gun.animationDuration = .8; 
    gun.animationRepeatCount = 1; 
    [gun startAnimating]; 
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(arc4random() % 300)/100 * NSEC_PER_SEC), dispatch_get_current_queue(),^{ 
    [self animateGun:leftGun withFilmStrip:[self getFilmStripForAction:gunShoot andTeam:nil withWeapon:nil]]; 
    }); 
} 

这段代码的代码背后的想法很简单:我有一个(UIImageView*)gun我与存储在(NSMutableArray *)frames,在随机时间的图像动画。 (UIImage *)filmstrip只是一个包含所有将用于动画的帧的图像。动画作品的第一次迭代,但问题出现在第二次迭代中,我得到-[UIImage _isResizable]: message sent to deallocated instance ...-[UIImage _contentStretchInPixels]: message sent to deallocated instance ...-[NSArrayI release]: message sent to deallocated instance ...。这发生在

gun.animationImages = frames; 

但我不明白为什么。我并没有要求解决我的问题,而只是为了帮助我理解这里发生的事情。谢谢。

+0

代码你如何调用这个函数?多次被称为? –

+0

我第一次用'[self animateGun:leftGun withFilmStrip:[self getFilmStripForAction:gunShoot andTeam:nil withWeapon:nil]]来调用它;'然后我离开'dispatch_after'完成它的工作。 – ov1d1u

+1

对我来说,似乎UIImageView和UIImage引用是问题,而且错误在于此方法之外。 – Mike

回答

0

ARC是一种无需手动保留/释放对象的机制。这是一个很好的网站,解释如何工作:http://longweekendmobile.com/2011/09/07/objc-automatic-reference-counting-in-xcode-explained/

尝试更改“leftGun”为“枪”。如果你通过伊娃使用它,我想这可能是某个时候被释放的那个。否则,LeftGun根本不在范围内。

下面是它应该是什么样子:

在您的.h文件中:

@property (nonatomic, strong) IBOutlet UIImageView *leftGun; 

在您.m文件:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(arc4random() % 300)/100 * NSEC_PER_SEC), dispatch_get_current_queue(),^{ 
    [self animateGun:gun withFilmStrip:[self getFilmStripForAction:gunShoot andTeam:nil withWeapon:nil]]; 
    }); 

而且,不太肯定 “gunShoot”来自。这应该是一个枚举?

EDIT

添加的leftGun属性应该如何定义的例子。在法国国内使用财产背后的原因是内存管理的目的。如果要释放或销毁属性的对象,只需将其设置为零,并且该属性将负责在需要时释放该对象。

+0

但是函数的每次调用都不是'frames'重新创建的吗? – ov1d1u

+0

啊!你是对的。但是,“leftGun”和“gunShoot”在哪里声明? –

+0

leftGun是在类的@接口中声明的IBOutlet。 'gunShoot'只是'enum'中的一个项目,它用于决定在'getFilmStripForAction'中使用哪个图片。com/fBu1mUZ2 – ov1d1u

-1

如果您将其标记为__block,您可能会阻止frames阵列的重新分配。

__block NSMutableArray *frames = [NSMutableArray array]; 

看到“The __block Storage Type.”

+0

该数组在块内部没有使用,而且它不是早期发布的数组。它似乎是阵列中的物体。 –

+0

该数组在块内用作'gun.animationImages = frames;'的引用,它持有图像的引用。 – Tassos

+0

该部分不在块内。 –

相关问题