2

我正在尝试理解自动引用计数,因为我来自高级编程语言 (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用存储在 中的图像进行动画处理。只是一个包含将用于动画的所有帧的图像。动画的第一次迭代有效,但问题出现在第二次迭代中,我得到or or 。这发生在(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;

但我不明白为什么。我不是要求修复我的问题,只是为了帮助我了解这里发生的事情。谢谢。

4

2 回答 2

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 ,如果必须,该属性将负责释放该对象。

于 2012-10-08T12:21:37.140 回答
-1
于 2012-10-08T13:34:05.683 回答