Управление памятью на NSMutableArray - PullRequest
0 голосов
/ 04 марта 2011

Я прочитал некоторые материалы об этом, затем я попытался написать простой приложение, но запутался, вот пример (с использованием шаблона 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];

И выпустил SpriteObject в методе func2, как вы можете видеть закомментированную строку.

Но приложение упало.

Затем я раскомментировал строку выпуска SpriteObject, но она все еще не работала.

Затем я удалил два autorelease в операторе возврата, и это сработало хорошо.

Может кто-нибудь дать что-нибудь предложение в соответствии с кодом выше ??? Заранее спасибо.

1 Ответ

1 голос
/ 06 марта 2011

О, мальчик, есть несколько проблем. Сначала не забудьте выпустить все, что вы называете «распределять, создавать, сохранять, копировать». См. Выпуск Objective C, автоматический выпуск и типы данных и Выпуск, Dealloc и ссылка на себя

Основная проблема заключается в том, что вы перезаписываете ранее созданные переменные. Например:

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

array = ...;

[выпуск массива];

Поэтому вы создаете утечку памяти и получаете проблемы с двойным выпуском. См. obj-c NSString и alloc / retain / release , чтобы узнать, как это сделать правильно.

...