views:

2440

answers:

3

Greetings,

I'm trying to draw a circle on a map. all the separate pieces of this project work independently but when I put them all together it breaks.

I setup my UI in my viewDidLoad, retaining most of it.

I then use touch events to call a my refresh map method:

-(void)refreshMap{

NSString *thePath = [NSString stringWithFormat:@"http://maps.google.com/staticmap?center=%f,%f&zoom=%i&size=640x640&maptype=hybrid",viewLatitude, viewLongitude, zoom];
NSURL *url = [NSURL URLWithString:thePath];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *mapImage = [[UIImage alloc] initWithData:data];

mapImage = [self addCircle:(mapImage) influence:(70) latCon:(320) lonCon:(320)];
NSLog(@"-- mapimageview retaincount %i",[mapImage retainCount]); 

mapImageView.image = mapImage;
[mapImage release];}

Setup like this it will load the map with a circle once, but if the map is refreshed again it crashes.

If I comment out the mapImage release it works repeatedly but causes a memory leak.

The addCircle method I'm using:

-(UIImage *)addCircle:(UIImage *)img radius:(CGFloat)radius latCon:(CGFloat)lat lonCon:(CGFloat)lon{
int w = img.size.width;
int h = img.size.height; 
lon = h - lon;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);

//draw the circle
CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
CGRect leftOval = {lat- radius/2, lon - radius/2, radius, radius};
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 0.3);
CGContextAddEllipseInRect(context, leftOval);
CGContextFillPath(context);

CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);

return [UIImage imageWithCGImage:imageMasked];}

Any insight/advise is greatly appreciated!

A: 

UIImage *mapImage = [[UIImage alloc] initWithData:data];

mapImage = [self addCircle:(mapImage) influence:(70) latCon:(320) lonCon:(320)];

That's not good. You're losing the reference to the contents of mapImage when you reassign it on the second line. The easiest way to fix this if probably to just add an additional variable, so you can keep track of both images.

Mark Bessey
Thank you for your response!I did try this suggestion, I created a new UIImage and assign the formatted image to it instead, but unfortunately I get the same result, if I don't deallocate the new image also my app leaks, else it crashes the 2nd time through.
Puppet
A: 

Mark Bessey was on the right track:

I have created a temp UIImage in my addcircle method, which allows me to release the cgimage and return my formatted UImage.

I also created a new UIImage for this to be returned to in my refreshMap method.

Thanks for the help!

Puppet
A: 

use this one

  • (void)loadView {

    UIView *view1=[[UIView alloc]initWithFrame:[[UIScreen mainScreen]applicationFrame]]; view1.backgroundColor=[UIColor redColor]; self.view=view1;

    mapimageview=[[UIImageView alloc]initWithFrame:view1.frame]; [view1 release];

    mapimageview.userInteractionEnabled=YES; mapimageview.backgroundColor=[UIColor whiteColor]; [self.view addSubview:mapimageview];

    NSString *thePath = [NSString stringWithFormat:@"http://maps.google.com/staticmap?center=%f,%f&zoom=%i&size=640x640&maptype=hybrid"]; NSURL *url = [NSURL URLWithString:thePath]; NSData *data = [NSData dataWithContentsOfURL:url]; mapImage = [[UIImage alloc] initWithData:data];

    mapimageview.image=mapImage;

    //NSString *thePath = [NSString stringWithFormat:@"http://maps.google.com/staticmap?center=%f,%f&zoom=%i&size=640x640&maptype=hybrid",viewLatitude, viewLongitude, zoom]; // NSURL *url = [NSURL URLWithString:thePath]; // NSData *data = [NSData dataWithContentsOfURL:url]; // UIImage *mapImage = [[UIImage alloc] initWithData:data];

}

  • (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch=[touches anyObject]; if([touch view]==mapimageview) { [self refreshMap];

     CGPoint p1=[touch locationInView:mapimageview];
    
    
     Xradious=p1.x;
    
    
     NSLog(@"...%f\n...",Xradious);
    

    }

}

-(void)refreshMap {

mapImage = [self addCircle:(mapImage) radius:(Xradious+35) latCon:(320) lonCon:(320)];
NSLog(@"-- mapimageview retaincount %i",[mapImage retainCount]);        

mapimageview.image = mapImage;
 //[mapImage release];

}

-(UIImage *)addCircle:(UIImage *)img radius:(CGFloat)radius latCon:(CGFloat)lat lonCon:(CGFloat)lon{ int w = img.size.width; int h = img.size.height; lon = h - lon; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);

//draw the circle
CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
CGRect leftOval = {lat- radius/2, lon - radius/2, radius, radius};
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 0.3);
CGContextAddEllipseInRect(context, leftOval);
CGContextFillPath(context);

CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);

 return [UIImage imageWithCGImage:imageMasked];

}