我正在尝试理解自动引用计数,因为我来自高级编程语言(Python),我正在开发一个使用Objective-C的这个功能的项目。我常常遇到ARC解除分配对象的问题,我稍后需要这些问题,但现在我得到了一个具体的例子,希望我能得到解释。
- (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)
ARC是一种无需手动保留/释放对象的机制。这是一个很好的网站,解释了它的工作原理:http://longweekendmobile.com/2011/09/07/objc-automatic-reference-counting-in-xcode-explained/
尝试将“leftGun”更改为“gun”。如果你通过ivar使用它,我认为这可能是在某些时候被解除分配的那个。否则,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”的来源。这应该是一个枚举吗?
修改强>
添加了如何定义leftGun
属性的示例。在ivar上使用属性的原因是出于内存管理的目的。如果要释放或销毁作为属性的对象,只需将其设置为nil,如果必须,属性将负责释放对象。
答案 1 :(得分:-1)
如果您将frames
数组标记为__block
,则可以阻止重新分配。
__block NSMutableArray *frames = [NSMutableArray array];