在方法中创建自动释放的对象并将其返回到实例变量会导致崩溃

发布于 2024-10-02 01:22:07 字数 2000 浏览 1 评论 0原文

我在方法中创建一个对象并将其返回给一个变量,这让我变得一团糟。正如这篇文章中那样,我知道我应该在这种情况,但是当我这样做时,它崩溃了。

我编写了一个方法来创建图像数组并返回该数组。它看起来像这样:

- (NSMutableArray *)createImagesFor:(NSString *)animName withFrames:(int)numberFrames {
    NSMutableArray *imageArray = [[NSMutableArray alloc] initWithCapacity:numberFrames];
    for (int i = 1; i <= numberFrames; ++i) {
        NSString *imageName = [[NSString alloc]initWithFormat:@"%@%i.png", animName, i];
        [imageArray addObject:[UIImage imageNamed:imageName]];
        [imageName release];
    }
    return imageArray;
}

我这样称呼它:

NSMutableArray *imageArray;
imageArray = [self createImagesFor:@"jumping" withFrames:2];
self.animationImages = imageArray;
[imageArray release];

但是,当我运行构建分析器时,它会编译,但有以下抱怨:

第 109 行分配的对象存在潜在泄漏
1. 方法返回一个 Objective-C 对象,其保留计数+1(拥有引用)
2. 对象作为拥有引用返回给调用者(单个保留计数转移给调用者)
3. 第 109 行分配的对象是从名称 ('createImagesFor:withFrames:') 不包含 'copy' 或以 'new' 或 'alloc' 开头的方法返回的。这违反了 Cocoa 内存管理指南中给出的命名约定规则(对象泄漏)

我查看了 内存管理文档,但除了自动释放变量(这会使其崩溃)之外,我不确定哪里出错了。这就是我自动释放它的方式:

NSMutableArray *imageArray = [[[NSMutableArray alloc] initWithCapacity:numberFrames]autorelease];

我尝试将 *imageArray 保留为 这里建议像这样:

NSMutableArray *imageArray;
[imageArray retain];
    imageArray = [self createImagesFor:@"jumping" withFrames:2];
    self.animationImages = imageArray;
    [imageArray release];

但这也会崩溃。

分析器建议我将该方法的名称更改为“newCreateImagesFor:withFrames:”之类的名称,但我不明白这是如何解决问题的?

感谢您的帮助。

迈克尔

I'm making a mess of creating an object in a method and returning it to a variable. As in this post I know I should autorelease an object in this case, but when I do, it crashses.

I have written a method to create an array of images, and return this array. It looks like this:

- (NSMutableArray *)createImagesFor:(NSString *)animName withFrames:(int)numberFrames {
    NSMutableArray *imageArray = [[NSMutableArray alloc] initWithCapacity:numberFrames];
    for (int i = 1; i <= numberFrames; ++i) {
        NSString *imageName = [[NSString alloc]initWithFormat:@"%@%i.png", animName, i];
        [imageArray addObject:[UIImage imageNamed:imageName]];
        [imageName release];
    }
    return imageArray;
}

I call it like this:

NSMutableArray *imageArray;
imageArray = [self createImagesFor:@"jumping" withFrames:2];
self.animationImages = imageArray;
[imageArray release];

However, when I run the build analyzer, it compiles but with the following complaint:

Potential leak of an object allocated on line 109
1. Method returns an Objective-C object with a +1 retain count (owning reference)
2. Object returned to caller as an owning reference (single retain count transferred to caller)
3. Object allocated on line 109 is returned from a method whose name ('createImagesFor:withFrames:') does not contain 'copy' or otherwise starts with 'new' or 'alloc'. This violates the naming convention rules given in the Memory Management Guide for Cocoa (object leaked)

I've had a look at the memory management document but other than autoreleasing the variable (which crashes it), I'm not sure where I'm going wrong. This is how I autoreleased it:

NSMutableArray *imageArray = [[[NSMutableArray alloc] initWithCapacity:numberFrames]autorelease];

I've tried retaining the *imageArray as suggested here like so:

NSMutableArray *imageArray;
[imageArray retain];
    imageArray = [self createImagesFor:@"jumping" withFrames:2];
    self.animationImages = imageArray;
    [imageArray release];

But this also crashes.

The analyzer suggests I change the name of the method to something like 'newCreateImagesFor:withFrames:' but I don't see how this fixes things?

Thanks for the help.

Michael

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

愿与i 2024-10-09 01:22:07

您应该将第一块代码的最后一行更改为 return [imageArray autorelease] 并摆脱第二部分中的释放(通常不需要释放方法调用返回的对象) 。这就是分析仪抱怨的内容。但是,我不明白为什么它会导致崩溃。

animationImages 属性是如何定义的?这可能是你问题的根源。

You should change the last line of first block of code to return [imageArray autorelease] and get rid of the release in the second part (you normally don't ever need to release objects returned by method calls). That's what the analyzer complaints are about. However, I don't see why it would cause a crash.

How is the animationImages property defined? That might be the source of your problems.

楠木可依 2024-10-09 01:22:07
    - (NSMutableArray *)createImagesFor:(NSString *)animName withFrames:(int)numberFrames {
    NSMutableArray *imageArray = [[NSMutableArray alloc] initWithCapacity:numberFrames];
    for (int i = 1; i <= numberFrames; ++i) {
        NSString *imageName = [[NSString alloc]initWithFormat:@"%@%i.png", animName, i];
        [imageArray addObject:[UIImage imageNamed:imageName]];
        [imageName release];
    }
    return imageArray;
}

返回一个 imageArray 对象,该对象的保留计数为 +1 但不会自动释放,clang 静态分析器会警告您这一点,这与命名约定有关,因为您的方法未命名类似于 newImagesFor...allocImagesFor...copyImagesFor...


NSMutableArray *imageArray;

[imageArray retain];
// sending message to nil, does nothing

imageArray = [self createImagesFor:@"jumping" withFrames:2];
// imageArray has a retain count of 1
// and it is an autoreleased object

self.animationImages = imageArray; 

[imageArray release]; 
// retain count = 0, will be dealloc'd, 
// however it is already in the autorelease pool, 
// it will be over-released at the end of current event run loop

当您声明 imageArray 时,它是一个指向类 NSMutableArray 的空指针,在您的情况下发送一条消息 retain 到一个空指针Objective-C 是可以的并且不会抛出异常。


如果您使用属性访问器来缓存 imageArray 对象,则应声明您的属性访问器以保留您分配给的对象。

@property (retain) NSMutableArray *imageArray;

既然您的方法正确返回了自动释放的 imageArray,并且你有一个正确的属性访问器,所需要的只是

NSMutableArray *imageArray;
imageArray = [self createImagesFor:@"jumping" withFrames:2];
self.animationImages = imageArray;
    - (NSMutableArray *)createImagesFor:(NSString *)animName withFrames:(int)numberFrames {
    NSMutableArray *imageArray = [[NSMutableArray alloc] initWithCapacity:numberFrames];
    for (int i = 1; i <= numberFrames; ++i) {
        NSString *imageName = [[NSString alloc]initWithFormat:@"%@%i.png", animName, i];
        [imageArray addObject:[UIImage imageNamed:imageName]];
        [imageName release];
    }
    return imageArray;
}

returns an imageArray object that has a retain count of +1 but not auto-released, clang static analyser will warn you about this, and it is all to do with naming convention, because your method is not named to be like newImagesFor... or allocImagesFor... or copyImagesFor....


NSMutableArray *imageArray;

[imageArray retain];
// sending message to nil, does nothing

imageArray = [self createImagesFor:@"jumping" withFrames:2];
// imageArray has a retain count of 1
// and it is an autoreleased object

self.animationImages = imageArray; 

[imageArray release]; 
// retain count = 0, will be dealloc'd, 
// however it is already in the autorelease pool, 
// it will be over-released at the end of current event run loop

When you declare imageArray, it is a null pointer to the class NSMutableArray, sending a message, in your case retain, to a null pointer in Objective-C is possible and will not throw an exception.


If you use a property accessor to cache your imageArray object, your property accessor should be declared to retain the object you assign to

@property (retain) NSMutableArray *imageArray;

Now that your method properly return an autoreleased imageArray, and you have a correct property accessor, all that's needed is

NSMutableArray *imageArray;
imageArray = [self createImagesFor:@"jumping" withFrames:2];
self.animationImages = imageArray;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文