Andrey Chernukha
Andrey Chernukha

Reputation: 21808

Cocos2d. Why loading texture asynchronously retains it?

I have discovered a weird thing - CCTexture2D object gets retained when it is loaded asynchronously either by usage of addImageAsync:(NSString*)path withBlock:(void(^)(CCTexture2D *tex))block or -(void) addImageAsync: (NSString*)path target:(id)target selector:(SEL)selector.

In order to verify this i have created a very simple project. Actually this is cocos2d template. I have two buttons, a png file mytexture.png and a function which prints memory being consumed in megabytes. This is the function:

void report_memory(void) {
struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(),
                               TASK_BASIC_INFO,
                               (task_info_t)&info,
                               &size);
if( kerr == KERN_SUCCESS ) {
    NSLog(@"Memory : %f", info.resident_size / 1024.0f / 1024.0f);
} else {
    NSLog(@"Error with task_info(): %s", mach_error_string(kerr));
}
}

While nothing happens and just cocos2d layer is displayed the memory is around 8 mb (on iPad). Let's click first button:

 [[CCTextureCache sharedTextureCache] addImageAsync:@"mytexture.png" withBlock:^(CCTexture2D *text){

            NSLog(@"Cache %@", [CCTextureCache sharedTextureCache]);

        }];

now the memory is around 24 mb. ok. let's click the second one:

[[CCTextureCache sharedTextureCache] removeTextureForKey:@"mytexture.png"];
 NSLog(@"Cache %@", [CCTextureCache sharedTextureCache]);

and the memory is still 24 mb!!! Why??? The only object which had reference to the texture was the cache, but it has removed it. Why is it still in memory? What referencing it? If i add a texture by using addImage: method it gets removed as i expect it to. So how to work it out? How to unload it from memory?

If you think that memory check function can give false data then i want to say that i have profiled the app with Instruments and it showed the same result.

Upvotes: 1

Views: 337

Answers (1)

CodeSmile
CodeSmile

Reputation: 64478

Prefer to measure memory usage with Instruments.

As for the actual issue:

  • any sprite or sprite frame will also retain the texture
  • it may take some time before memory is freed, ie when the autoreleasepool is purged which means measuring memory usage directly after purge gives you the wrong impression (hence use Instruments)

Upvotes: 1

Related Questions