tags:

views:

150

answers:

3

I a trying to make a mutableCopy of a planet object that contains 5 instance variables (one of them being an NSMutableArray of string literals. My problem is that I am unsure how to set the newPlanet>data to a copy of self>data, does that make sense?

-(id) mutableCopyWithZone: (NSZone *) zone {
    Planet *newPlanet = [[Planet allocWithZone:zone] init];
    NSLog(@"_mutableCopy: %@", [newPlanet self]);
    [newPlanet setName:name];
    [newPlanet setType:type];
    [newPlanet setMass:mass];
    [newPlanet setIndex:index];

    // NSMutableArray *data; HOW TO: newPlanet>data = self>data? 

    return(newPlanet);
}

EDIT_001:

Based on the comments by Chuck & bbum I updated my method and added the following ...

@property(retain) NSMutableArray *data;
@synthesize data;

.

-(id) mutableCopyWithZone: (NSZone *) zone {
    Planet *newPlanet = [[Planet allocWithZone:zone] init];
    NSLog(@"_mutableCopy: %@", [newPlanet self]);
    [newPlanet setName:name];
    [newPlanet setType:type];
    [newPlanet setMass:mass];
    [newPlanet setIndex:index];

    NSMutableArray *copiedArray = [[self data] mutableCopyWithZone:zone];
    [newPlanet setData: copiedArray];
    [copiedArray release];

    return(newPlanet);
}

much appreciated

gary

+1  A: 

Did you try something like [newPlanet setData:[[self data] mutableCopyWithZone:zone]]; ?

Asher Dunn
This will leak if your data setter retains its argument (which is how it normally works).
Chuck
+3  A: 

Nothing too special here. Something like this:

NSMutableArray *copiedData = [[self data] mutableCopyWithZone:zone];
newPlanet.data = copiedData;
[copiedData release];
Chuck
I now realise this might be bad naming, but data in the OP is a NSMutableArray, does that matter. I will try anyway, many thanks.
fuzzygoat
The `data` name did confuse my typing, but this will work for any class that implements NSMutableCopying, which NSMutableArray does.
Chuck
Since he's creating a new object and won't be wasting memory, I'd probably opt for simplicity in this case: `newPlanet.data = [[[self data] mutableCopyWithZone:zone] autorelease];` (Autorelease pools aren't always evil...)
Quinn Taylor
+1  A: 

You probably want

newPlanet->data = [data mutableCopyWithZone:zone];

Be aware that if you use a setter (such as dot-access, or setData:), then you will be triggering another retain, so you should handle that appropriately.

Ciarán Walsh