views:

270

answers:

1

Hi,

I'm having a few problems with some Objective-C and would appreciate some pointers.

So I have a class MapFileGroup which has the following simple interface (There are other member variables but they aren't important):

@interface MapFileGroup : NSObject {
 NSMutableArray *mapArray;

}

@property (nonatomic, retain) NSMutableArray *mapArray;

mapArray is @synthesize'd in the .m file.

It has an init method:

-(MapFileGroup*) init
  {
    self = [super init];
    if (self)
    {
       mapArray = [NSMutableArray arrayWithCapacity: 10];
    }

    return self;
  }

It also has a method for adding a custom object to the array:

-(BOOL) addMapFile:(MapFile*) mapfile
{
if (mapfile == nil) return NO;

mapArray addObject:mapfile];
return YES;
}

The problem I get comes when I want to use this class - obviously due to a misunderstanding of memory management on my part.

In my view controller I declare as follows:

(in the @interface):

MapFileGroup *fullGroupOfMaps;

With @property @property (nonatomic, retain) MapFileGroup *fullGroupOfMaps;

Then in the .m file I have a function called loadMapData that does the following:

MapFileGroup *mapContainer = [[MapFileGroup alloc] init];
// create a predicate that we can use to filter an array

// for all strings ending in .png (case insensitive) NSPredicate *caseInsensitivePNGFiles = [NSPredicate predicateWithFormat:@"SELF endswith[c] '.png'"];

mapNames = [unfilteredArray filteredArrayUsingPredicate:caseInsensitivePNGFiles];
[mapNames retain];

NSEnumerator * enumerator = [mapNames objectEnumerator];
NSString * currentFileName;
NSString *nameOfMap;
MapFile *mapfile;


while(currentFileName = [enumerator nextObject]) {
  nameOfMap = [currentFileName substringToIndex:[currentFileName length]-4]; //strip the extension

mapfile = [[MapFile alloc] initWithName:nameOfMap];
[mapfile retain];
// add to array
[fullGroupOfMaps addMapFile:mapfile];

}

This seems to work ok (Though I can tell I've not got the memory management working properly, I'm still learning Objective-C); however, I have an (IBAction) that interacts with the fullGroupOfMaps later. It calls a method within fullGroupOfMaps, but if I step into the class from that line while debugging, all fullGroupOfMaps's objects are now out of scope and I get a crash.

So apologies for the long question and big amount of code, but I guess my main question it:

How should I handle a class with an NSMutableArray as an instance variable? What is the proper way of creating objects to be added to the class so that they don't get freed before I'm done with them?

Many thanks

+2  A: 
dreamlax
Thanks for the help - I've been reading through the memory management rules but still get tripped up every now and again (bit too used to new and free I think). I'm still having a problem with the objects going out of scope within the array however, `mapfile = [[MapFile alloc] initWithName:nameOfMap];[mapfile retain];// add to array[fullGroupOfMaps addMapFile:mapfile];` is adding them ok but they go out of scope. I thought that addObject would perform a retain?
davbryn
My bad, going between C++ and Obj-C doesn't make life easy. I'd been creating the @properties for my classes but not using self.variable_name to get/set so no retaining was taking place :(
davbryn