简体   繁体   English

为什么我的NSArray被释放?

[英]Why does my NSArray get deallocated?

I'm trying to understand Automatic Reference Counting, as I come from a high-level programming language (Python) and I'm working on a project which use this feature of Objective-C. 我试图理解自动引用计数,因为我来自高级编程语言(Python),并且我正在一个使用Objective-C此功能的项目中进行工作。 I often get problems with ARC deallocating objects which I need later, but now I got a concrete example for which I hope I'll get an explanation. 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]];
  });
}

The idea behind this snippet of code is simple: I have a (UIImageView*)gun which I animate with the images stored in (NSMutableArray *)frames , at random times. 这段代码背后的想法很简单:我有一个(UIImageView*)gun ,我可以随机地对(NSMutableArray *)frames存储的图像进行动画处理。 (UIImage *)filmstrip is just an image which contains all the frames which will be used on animation. (UIImage *)filmstrip只是一个图像,其中包含将在动画上使用的所有帧。 The first iteration of animation works, but the problems appears on the second iteration, where I get -[UIImage _isResizable]: message sent to deallocated instance ... or -[UIImage _contentStretchInPixels]: message sent to deallocated instance ... or -[NSArrayI release]: message sent to deallocated instance ... . 动画的第一个迭代有效,但是问题出现在第二个迭代中,在该迭代中,我得到-[UIImage _isResizable]: message sent to deallocated instance ...-[UIImage _contentStretchInPixels]: message sent to deallocated instance ...-[NSArrayI release]: message sent to deallocated instance ... This happens at 这发生在

gun.animationImages = frames;

but I don't understand why. 但我不明白为什么。 I'm not requesting a fix for my issue, but just to help me understand what's happening here. 我并不是要解决此问题,而只是为了帮助我了解此处发生的情况。 Thanks. 谢谢。

ARC is a mechanism that removes the need to manually retain/release objects. ARC是一种无需手动保留/释放对象的机制。 Here's a nice site that explains how this works: http://longweekendmobile.com/2011/09/07/objc-automatic-reference-counting-in-xcode-explained/ 这是一个很好的网站,解释了它的工作原理: http : //longweekendmobile.com/2011/09/07/objc-automatic-reference-counting-in-xcode-explained/

Try changing "leftGun" for "gun". 尝试将“ gun”改为“ leftGun”。 I think that's probably the one that gets deallocated at some point, if you're using it through an ivar. 我认为,如果通过ivar使用它,那可能是在某个时候释放的对象。 Otherwise, leftGun simply isn't in the scope. 否则,leftGun根本不在范围内。

Here's what it should look like: 它应该是这样的:

In your .h file: 在您的.h文件中:

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

In your .m file: 在您的.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]];
  });

Also, not quite sure where "gunShoot" is coming from. 另外,还不确定“ gunShoot”的来源。 Is that supposed to be an enum? 那应该是枚举吗?

EDIT 编辑

Added an example of how the leftGun property should be defined. 添加了如何定义leftGun属性的示例。 The reason behind using a property over an ivar is for memory management purposes. 在ivar上使用属性的原因是出于内存管理的目的。 If you want to release or destroy an object that is a property, simply set it to nil and the property will take care of releasing the object if it has to. 如果要释放或销毁作为属性的对象,只需将其设置为nil即可,如果需要,该属性将负责释放该对象。

You may prevent the deallocation of the frames array if you mark it as __block . 如果将其标记为__block则可以防止frames数组的重新分配。

  __block NSMutableArray *frames = [NSMutableArray array];

see “The __block Storage Type.” 请参见“ __block存储类型”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM