0

I read some materials about this then I tried to wrote a simple app but got confused, here is the sample (using cocos2d template):

MySpriteObject class:

#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 class:

#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

And in the "HelloWorldScene.m" init method:

-(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;
}

The code posted above works fine (at least no crash), but I think there is memory leak out there.

At first, I had the fun1 fun2 method return the array like this:

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

And released the SpriteObject in the func2 methoed as you can see the commented line.

But the app crashed.

Then I uncommented the SpriteObject release line but it still crashed.

Then I deleted the two autorelease in the return statement and it worked fine.

Can somebody give something suggestion according to the code above??? Thanks in advance.

supersurabbit
  • 441
  • 1
  • 8
  • 14

1 Answers1

1

Oh boy, there are multiple problems. At first remember to release everything you called "alloc, new, retain, copy" upon. See Objective C release, autorelease, and data types and Release, Dealloc, and the Self reference

The basic problem here is, that you are overwriting previously created variables. For example:

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

array = ... ;

[array release];

Therefore you create a memory leak and get double release trouble. See obj-c NSString and alloc / retain / release for how to do it right.

Community
  • 1
  • 1
Jonas Bötel
  • 4,452
  • 1
  • 19
  • 28