NSMutableArray 上的内存管理

Posted

技术标签:

【中文标题】NSMutableArray 上的内存管理【英文标题】:Memory Management on NSMutableArray 【发布时间】:2011-03-04 01:47:24 【问题描述】:

我阅读了一些关于此的材料,然后我尝试写一个简单的 app 但有点困惑,这里是示例(使用 cocos2d 模板):

MySpriteObject 类:

#import <Foundation/Foundation.h>
#import "cocos2d.h"

@interface MySpriteObject : CCNode 
    CCSprite *mySprite;
    NSString *spriteInfo;


@property(nonatomic,retain) CCSprite *mySprite;
@property(nonatomic,retain) NSString *spriteInfo;
@end


#import "MySpriteObject.h"

@implementation MySpriteObject
@synthesize mySprite;
@synthesize spriteInfo;

-(id) init

    NSLog(@"MySpriteObject init");
    if ((self = [super init])) 

        self.mySprite = [CCSprite spriteWithFile:@"Icon.png"];
        self.spriteInfo = [[[NSString alloc] initWithFormat:@"sprite info"] autorelease];
    

    return (self);


-(void)dealloc

    NSLog(@"MySpriteObject dealloc");
    [self.spriteInfo release];
    [super dealloc];


@end

MyObjectManager 类:

#import "cocos2d.h"
#import "MySpriteObject.h"

@class MySpriteObject;
@interface MyObjectManager : CCNode 



+(MyObjectManager *)sharedMyObjectManager;
-(NSMutableArray *)func1;
-(NSMutableArray *)func2;

@end


#import "MyObjectManager.h"
#import "MySpriteObject.h"

@implementation MyObjectManager

static MyObjectManager *_sharedMyObjectManager = nil;

+(MyObjectManager *)sharedMyObjectManager

    NSLog(@"MyObjectManager sharedMyObjectManager");
    if (!_sharedMyObjectManager) 

        if( [ [MyObjectManager class] isEqual:[self class]] )
            _sharedMyObjectManager = [[MyObjectManager alloc] init];
        else
            _sharedMyObjectManager = [[self alloc] init];
    

    return _sharedMyObjectManager;


-(id)init
  
    NSLog(@"MyObjectManager init");
    if( (self = [super init]) ) 
    
    return self;


-(void)dealloc

    NSLog(@"MyObjectManager dealloc");
    [super dealloc];


-(NSMutableArray *)func1

    NSMutableArray *array1 = [[NSMutableArray alloc] init];
    array1 = [self func2];
    return array1;


-(NSMutableArray *)func2;

    NSMutableArray *array2 = [[NSMutableArray alloc] init];
    for (int i = 0; i < 3; i++) 

        MySpriteObject *mySpriteObject = [[MySpriteObject alloc] init];
        [array2 addObject:mySpriteObject];

        //[mySpriteObject release];
    
    return array2;

@end

并且在“HelloWorldScene.m”初始化方法中:

-(id) init

    if( (self=[super init] )) 

        NSMutableArray *array = [[NSMutableArray alloc] init];
        array = [[MyObjectManager sharedMyObjectManager] func1];
        for (int i = 0; i < array.count; i++)  
            MySpriteObject *s = [[MySpriteObject alloc] init];
            s = [array objectAtIndex:i];
            NSLog(@"%@", s.spriteInfo);
            [s release];
        
        [array release];
    
    return self;

上面发布的代码工作正常(至少没有崩溃),但我认为有 内存泄漏。

起初,我让 fun1 fun2 方法返回这样的数组:

return [array1 autorelease];
return [array2 autorelease];

并在func2方法中释放SpriteObject,如注释行所示。

但是应用崩溃了。

然后我取消注释 SpriteObject 发布行,但它仍然崩溃。

然后我删除了return语句中的两个autorelease,它起作用了 很好。

有人可以根据上面的代码给出一些建议吗??? 提前致谢。

【问题讨论】:

【参考方案1】:

哦,男孩,有多个问题。首先记得释放所有你称之为“alloc、new、retain、copy”的东西。见Objective C release, autorelease, and data types和Release, Dealloc, and the Self reference

这里的基本问题是,您正在覆盖以前创建的变量。例如:

NSMutableArray *array = [[NSMutableArray alloc] init];

数组 = ... ;

[数组释放];

因此,您会造成内存泄漏并遇到双重释放问题。请参阅obj-c NSString and alloc / retain / release 了解如何正确操作。

【讨论】:

以上是关于NSMutableArray 上的内存管理的主要内容,如果未能解决你的问题,请参考以下文章

在 NSMutableArray 中保留唯一对象的 id

无法将对象从块添加到 NSMutableArray

iOS内存管理--NSArray与NSMutableArray用copy修饰还是strong

iOS内存管理--NSArray与NSMutableArray用copy修饰还是strong

在其他功能中保留计数= 0?内存管理问题?

如何在ios中分隔数组