views:

326

answers:

4

Hi everyone, I was wondering if I need to release a copied NSObject? For example, I create only one dictionary that I copy into an array:

Code:

for (int num = 0; num < [object count]; num++) {
    [dictionary setObject:[object objectAtIndex:num] forKey:@"x"];
    [array addObject:[dictionary copy]];
}

Do I have to release the dictionary? If yes, when?

Thanks

+8  A: 

Yes, you do. In this case, you should probably release the copy immediately after adding it to the array, because the array retains anything added to it:

 NSDictionary *copied = [dictionary copy];
 [array addObject:copied];
 [copied release];
Noah Witherspoon
Thanks for the info!
ncohen
+3  A: 

This fragment from documentation:

- (id)copy

Return Value The object returned by the NSCopying protocol method copyWithZone:, where the zone is nil.

Discussion This is a convenience method for classes that adopt the NSCopying protocol. An exception is raised if there is no implementation for copyWithZone:.

NSObject does not itself support the NSCopying protocol. Subclasses must support the protocol and implement the copyWithZone: method. A subclass version of the copyWithZone: method should send the message to super first, to incorporate its implementation, unless the subclass descends directly from NSObject.

Special Considerations If you are using managed memory (not garbage collection), this method retains the new object before returning it. The invoker of the method, however, is responsible for releasing the returned object.

Victor
+2  A: 

With copy, you take ownership of the returned object. Containers also take ownership of the objects added to them.
As a result, you have to relinquish ownership of the copy as Noah pointed out. The Cocoa memory management guidelines contain a section noting how to work with containers.

Georg Fritzsche
A: 

Its hard to tell, without seeing where you create dictionary, whether this is sensible anyway. If there are no other members in dictionary, it would be simpler (though arguably harder to read :) to do something like

for (int num = 0; num < [object count]; num++) {
    [array addObject:[NSDictionary
                           dictionaryWithObject:[object objectAtIndex:num]
                                        forKey:@"x"
                     ]
    ]
}

Thats going to give you real NSDictionary objects in your array, rather than the NSMutableDictionary copies that you are creating.

Jeff
On what grounds do you claim that a copy of an NSMutableDictionary would not be a “*real* NSDictionary”?
Peter Hosey
On the grounds that a *real* NSDictionary will throw errors if you try to insert objects into it.
Jeff