views:

1322

answers:

3

I'm having trouble with a snippet of code. I'm trying to add an instance of CLLocationCoordinate2D to a NSMutable array using the addObject method, but whenever the line is executed, my app crashes. Is there anything obvious wrong with this code?

The crash is on this line:

[points addObject:(id)new_coordinate];

Polygon.m:

#import "Polygon.h"

@implementation Polygon
@synthesize points;

- (id)init {
    self = [super init];
    if(self) {
        points = [[NSMutableArray alloc] init];
    }
    return self;
}


-(void)addPointLatitude:(double)latitude Longitude:(double)longitude {
 NSLog(@"Adding Coordinate: [%f, %f] %d", latitude, longitude, [points count]);
 CLLocationCoordinate2D* new_coordinate = malloc(sizeof(CLLocationCoordinate2D));
 new_coordinate->latitude = latitude;
 new_coordinate->longitude = longitude;
 [points addObject:(id)new_coordinate];
 NSLog(@"%d", [points count]);
}


-(bool)pointInPolygon:(CLLocationCoordinate2D*) p {
 return true;
}


-(CLLocationCoordinate2D*) getNEBounds {
 ...
}

-(CLLocationCoordinate2D*) getSWBounds {
 ...
}


-(void) dealloc {
 for(int count = 0; count < [points count]; count++) {
  free([points objectAtIndex:count]);
 }

 [points release];
 [super dealloc];
}

@end
+5  A: 

You can only add NSObject-derived objects to an array. You should encapsulate the data inside a proper object (for example NSData).

For example:

CLLocationCoordinate2D* new_coordinate = malloc(sizeof(CLLocationCoordinate2D));
    new_coordinate->latitude = latitude;
    new_coordinate->longitude = longitude;
    [points addObject:[NSData dataWithBytes:(void *)new_coordinate length:sizeof(CLLocationCoordinate2D)]];
    free(new_coordinate);

retrieving the object:

CLLocationCoordinate2D* c = (CLLocationCoordinate2D*) [[points objectAtIndex:0] bytes];
Philippe Leybaert
I'll try that later today - thanks Philippe!
Mr. Matt
To be precise, you can add objects that conform to the NSObject protocol to an NSArray. Not all objects that meet that requirement are derived from NSObject.
NSResponder
The nice thing about putting the bytes in an NSData is that the NSData will claim ownership of the malloc'd block and free it when the NSData object itself is released (unless you use `dataWithBytesNoCopy:`).
Dave DeLong
It is much better to use a stack variable here and NSValue than using NSData and pointers. His example is just leaking memory anyway.
Jason Coco
A: 

You can use the CFArrayCreateMutable function with custom callbacks to create a mutable array that doesn't retain/release.

rpetrich
+2  A: 

The proper way to do this is to encapsulate the data inside a NSValue, which is specifically for putting C types in NSArrays and other collections.

mrueg