0

EDIT: I tried using the push/pop thing, but now it crashes.

I have a feeling what I'm attempting to do is way off.. Is there any way to just get core graphics showing up on the screen? I need something thats able to be updated every frame, like drawing a line between two points that always move around.. Even if someone knows of a complete alternative Ill try it.

in .h

CGContextRef context;

in .m

in init method

int width = 100;
int height = 100;

void *buffer = calloc(1, width * height * 4);
context = CreateBitmapContextWithData(width, height, buffer);

CGContextSetRGBFillColor(context, 1, 1, 1, 1);
CGContextAddRect(context, CGRectMake(0, 0, width, height));
CGContextFillPath(context);

CGImageRef image = CGBitmapContextCreateImage(context);

hud_sprite = [CCSprite spriteWithCGImage:image key:@"hud_image1"];

free(buffer);
free(image);

hud_sprite.anchorPoint = CGPointMake(0, 0);
hud_sprite.position = CGPointMake(0, 0);

[self addChild:hud_sprite z:100];

in a method I call when I want to update it.

int width = 100;
int height = 100;

UIGraphicsPushContext(context);

    CGContextClearRect(context, CGRectMake(0, 0, width, height)); //<-- crashes here. bad access...

    CGContextSetRGBFillColor(context, random_float(0, 1),random_float(0, 1),random_float(0, 1), .8);
    CGContextAddRect(context, CGRectMake(0, 0, width, height));
    CGContextFillPath(context);

    CGImageRef image = CGBitmapContextCreateImage(context);

UIGraphicsPopContext();

//CGContextRelease(ctx);

[[CCTextureCache sharedTextureCache] removeTextureForKey:@"hud_image1"];
[hud_sprite setTexture:[[CCTextureCache sharedTextureCache] addCGImage:image forKey:@"hud_image1"]];

free(image);
PeteBob
  • 55
  • 1
  • 5

1 Answers1

0

You are calling UIGraphicsPushContext(context). You must balance this with UIGraphicsPopContext(). Since you're not calling UIGraphicsPopContext(), you are leaving context on UIKit's graphics context stack, so it never gets deallocated.

Also, you are calling UIGraphicsBeginImageContext, which creates a new graphics context that you later release (correctly) by calling UIGraphicsEndImageContext. But you never use this context. You would access the context by calling UIGraphicsGetCurrentContext, but you never call that.

UPDATE

Never call free on a Core Foundation object!

You are getting a CGImage (which is a Core Foundation object) with this statement:

CGImageRef image = CGBitmapContextCreateImage(context);

Then later you are calling free on it:

free(image);

You must never do that.

Go read the Memory Management Programming Guide for Core Foundation. When you are done with a Core Foundation object, and you have ownership of it (because you got it from a Create function or a Copy function), you must release it with a Release function. In this case you can use either CFRelease or CGImageRelease:

CGImageRelease(image);

Furthermore, you are allocating buffer using calloc, then passing it to CreateBitmapContextWithData (which I guess is your wrapper for CGBitmapContextCreateWithData), and then freeing buffer. But context keeps a pointer to the buffer. So after you free(buffer), context has a dangling pointer. That's why you're crashing. You cannot free buffer until after you have released context.

The best way to handle this is to let CGBitmapContextCreateWithData take care of allocating the buffer itself by passing NULL as the first (data) argument. There is no reason to allocate the buffer yourself in this case.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Thanks for the quick answers, but now I am running into more problems.. I edited the post with all the relevant code. – PeteBob Oct 08 '12 at 20:49
  • Ok, everything works flawlessly now, thanks so much. and I will read that document... I come from a basic language where memory is handled way more for you so allot is new... anyways, thanks again. I was using free allot of places for my one time created graphics as well.. and I see sending NULL thru the create context method makes allot more sense.. thanks for that! :D – PeteBob Oct 08 '12 at 21:46