PDA

View Full Version : Stand alone/direct initialization (without object instance)




alter
Jul 19, 2011, 01:54 AM
Hello everyone,

New here. I have a question related to initialization and memory.
I have a class (I am using cocos2D but is related to general Objective-C i guess) with initialization as follows:
@implementation MyClass
+(id) initializeMyClass
{
return [[[self alloc] initMyClass] autorelease];
}

-(id) initMyClass
{
if (([self = [super init]))
{
}
return self;
}

-(void) dealloc
{
NSLog(@"Deallocating");//I also used CCLOG instead.
[super dealloc];
}
@end

I initialize this class in another class without an object:
[MyClass initializeMyClass];

This works fine but the MyClass' dealloc method is not called and crashes since some resources are not freed.

This is totally puzzling and can't find anything online. If anyone would suggest a solution or an alternative method, i'd really appreciate it.

Thank you.



admanimal
Jul 19, 2011, 02:17 AM
We need to see all relevant parts of the actual code that is crashing in order to figure out what is wrong.

jiminaus
Jul 19, 2011, 02:24 AM
Never mind. I though you were trying to do the singleton pattern. But if you need dealloc, then maybe you're not. It seems you just want initializeMyClass to be a poorly named convenience constructor.

alter
Jul 19, 2011, 03:13 AM
Thanks for the replies.

Here's the actual class:
@implementation Test
+(id) initializeFade:(CCNode *)sprite
{
return [[self alloc] initWithSprite:sprite];
}

-(id) initWithSprite:(CCNode *)sprite
{
if ((self = [super init]))
{
spritePointer = (CCSprite *)sprite;
[[CCScheduler sharedScheduler] scheduleUpdateForTarget:self priority:0 paused:NO];//Removing this code solves the crash but this code is indispensable in this case
CCLOG(@"test initialized");
}
return self;
}

-(void) update:(ccTime)delta
{
if (spritePointer.opacity < 255)
spritePointer.opacity += 1;

}

-(void) dealloc
{
CCLOG(@"test deallocated");
[[CCScheduler sharedScheduler] unscheduleUpdateForTarget:self];//The crash seems to occur because the scheduler is not unscheduled here
[super dealloc];
}

This is how i invoke it in another class:
[Test initializeFade:slide1];

As i said this is implementing cocos2D and am actually trying to emulate the cocos2D style actions. Example:
[CCFadeIn actionWithDuration:2.0f];

The crash seems to occur due to the scheduler not being unscheduled in the dealloc method.

jiminaus
Jul 19, 2011, 03:35 AM
When is the object alloc'ed and init'ed in initializeFade: ever released? When do you want it to be released?

alter
Jul 19, 2011, 03:51 AM
Oops sorry. I forgot to type in autorelease.
This is the actual:
+(id) initializeFade:(CCNode *)sprite
{
return [[[self alloc] initWithSprite:sprite] autorelease];
}

I want the it it to be released when the class calling
[Test initializeFade:slide1];

is deallocated.

Please ask any more details if i'm not clear.

jiminaus
Jul 19, 2011, 07:36 AM
I'm not sure you understand how autorelease works. Autorelease arranges for release to be sent "sometime later". In practice, that's at the end of the current event.

Is this literally how you using initializeFade:? You're not using or assigning the returned pointer?

alter
Jul 19, 2011, 08:57 AM
Yes, this is how i'm trying to initialize and not assigning the returned pointer.

If you're familiar with the Cocos2D framework, you might have come across its actions.

Like suppose you want an image/sprite to fade away, you use the Cocos2D's actions like:
[image1 runAction:[CCFadeOut actionWithDuration:1.0f]];

I thought my method would have been simpler than this method. The problem seems to be that my dealloc method doesn't seem to be called.

Any suggestions on how to emulate this type of action?

admanimal
Jul 19, 2011, 03:35 PM
The problem seems to be that my dealloc method doesn't seem to be called.


The shared CCScheduler instance that you are using in the init method must be retaining self, preventing it from being dealloc'ed even though the Test class itself releases it. Presumably that unschedule method in dealloc would release the object if it was ever called, but you're obviously going to have to do that prior to dealloc.

alter
Jul 19, 2011, 09:59 PM
The shared CCScheduler instance that you are using in the init method must be retaining self, preventing it from being dealloc'ed even though the Test class itself releases it. Presumably that unschedule method in dealloc would release the object if it was ever called, but you're obviously going to have to do that prior to dealloc.

You're absolutely right! The CCScheduler IS retaining self. I just used NSTimer instead and invalidated it appropriately and it works! You can also use the CCScheduler's unscheduleAllSelectors method.

Thank you and also to jiminaus for your time and help!