On Nov 13, 2010, at 8:57 AM, William Squires wrote:

> Let's say I have some sample code that looks like:
> 
> -(NSMutableSet *)allOddNumbersExcept5Set
> {
> NSMutableSet *results = [[NSMutableSet alloc] initWithCapacity:1];
> 
> for (int i=1; i<=10; i+=2)
>  {
>  if (i != 5)
>    {
>    NSString *testNumber = [NSString stringWithFormat:"%d", i];
>    // testNumber should now be an autoreleased NSString
>    [results addObject:testNumber];
>    }
>  }
> return results;
> }

You should use NSNumbers to represent numbers as objects.

You are leaking the set.  By the naming conventions, a caller of 
-allOddNumbersExcept5Set does not receive an ownership responsibility.  That 
leaves this method with the responsibility of discharging the ownership 
responsibility by releasing the set.  You'd do that by sending it -autorelease, 
since you want it to live long enough to reach the caller.


> 1) Do mutable containers (NSMutableArray, NSMutableDictionary, NSMutableSet) 
> always send the 'retain' message to objects added with the 'addObject:' 
> message?

Yes, but you shouldn't care.  What you care about is whether your code handles 
its responsibilities properly.  The collection classes are in charge of 
handling their responsibilities properly, and you should just assume that they 
do.

It is documented that they extend the life of the contained objects for as long 
as they are contained.

(And this is irrespective of their mutability.)

> 2) When you retrieve the results from the collection, does the object 
> reference you get back have the same retain count as the one in the 
> container? (i.e. if I add an object to an NSMutableArray (held in an 
> @property) in one method, and retrieve it in another, will I get a retain 
> count of 1 or 2?)

You _really_ don't care about retain counts.  Don't pay any attention to them.  
They will only mislead and confuse you.

Also, this juxtaposition of "the object reference you get back" vs. "the one in 
the container" is very confused. Object references don't have retain counts.  
Objects have retain counts.  You receive a pointer to the object that is in the 
container.  Since the object you receive a pointer to and the object in the 
container are one and the same, they have the same retain count.

> 3) Will the above code autorelease the 'testNumber' the second (and third, 
> and fourth...) times through the loop when it gets another autoreleased 
> NSString, or will it just re-use the existing one?

Each time through the loop, you are asking for a different string.  Whether 
that string is autoreleased or not is an open question (it might in fact be a 
singleton that lives for the life of the process).  What is definite is that 
you do not receive an ownership responsibility and so should not release it 
(unless you acquire an ownership responsibility by retaining it).  You can know 
this by the memory management rules and the naming conventions.

> 4) Would I be better off with:
> 
> -(NSMutableSet *)allOddNumbersExcept5Set
> {
> NSMutableSet *results = [[NSMutableSet alloc] initWithCapacity:1];
> 
> for (int i=1; i<=10; i+=2)
>  {
>  if (i != 5)
>    {
>    NSString *testNumber = [[NSString alloc] initWithFormat:@"%d", i];
>    [results addObject:testNumber];
>    [testNumber release];
>    }
>  }
> return results;
> }
> 
> instead?

In this case, you do receive an ownership responsibility for the string 
(because you called +alloc), and you correctly discharge that responsibility by 
releasing it.  Both this and the previous code were correctly handling the 
memory management of the string.

This latter technique keeps the object out of the autorelease pool and so is 
slightly more efficient.  The efficiency gain is small enough that it doesn't 
matter when targeting Mac OS X, but Apple does recommend this approach in the 
more memory constrained environment of iOS apps.

The former technique is simpler (which counts for a lot), more convenient, and 
less prone to errors.  (For example, if you come back to a piece of code some 
time later and add in an early return path, it's easy to forget that you need 
to release the string.)

Regards,
Ken

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to