ABAddressBookCopyArrayOfAllPeople returns autoreleased NSArray?

Discussion in 'iPhone/iPad Programming' started by ashokmatoria, Nov 2, 2011.

  1. ashokmatoria, Nov 2, 2011
    Last edited by a moderator: Nov 2, 2011

    macrumors newbie

    Does ABAddressBookCopyArrayOfAllPeople returns an autorelease'd object?

    I was reviewing a code piece (see below) & I want your feedback over memory leak(s) over this statement. Can you pls explain this statement?

    		NSMutableArray *peopleArray = [[(NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook) autorelease] mutableCopy];
    peopleArray doesn't release have any release/autorelease call after this statement.


    I'm pretty sure that peopleArray (a mutableCopy) needs to be released explicitly before the enclosing block ends. Currently it has a memory leak due to the absence of [peopleArray release] statement.

    As far as inner array is concerned, I believe its right to release (or autorelease) it since that function ABAddressBookCopyArrayOfAllPeople doesn't return an autorelease'd array.

    Pls let me know if anyone disagree or has different view point.
  2. RonC, Nov 2, 2011
    Last edited: Nov 2, 2011

    macrumors regular

    According to the Advanced Memory Management Programming Guide, you own any object you create, and you create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy”.

    Question 1: Does peopleArray leak?
    Since mutableCopy begins with mutableCopy, you own it. That means you need to either pass off that ownership OR release it.

    I'd say your code example creates a leak if there is no subsequent release on that object AND that block exits.

    By a subsequent release I mean that the automatic variable peopleArray is later assigned to a property/ivar and that property/ivar is subsequently released, or similarly the containing method could return the value and presuming the containing method begins with alloc, new, copy, or mutableCopy, would imply that the returned value is owned and needs to be released.

    Question 2: Is autorelease on result of ABAddressBookCopyArrayOfAllPeople correct?

    I'd say yes, using the same argument as above - the Copy in ABAddressBookCopyArrayOfAllPeople implies that it returns a retained object, and hence releasing it is necessary. A quick look at the documentation for ABAddressBookCopyArrayOfAllPeople doesn't say one way or the other, so we are left to infer its ownership semantics from its name.
  3. macrumors 65816


    This code snippet confirms that the returned CFArray is not (could not be?) auto-released.
  4. macrumors 68030


    The naming conventions for CF functions are analogous to those for the Objective C frameworks, but not identical. Look up Create Rule and Get Rule in the docs.
  5. RonC, Nov 3, 2011
    Last edited: Nov 3, 2011

    macrumors regular

    I looked at the code snippet you referenced and I don't understand what you mean here. Do you mean that instead of autorelease it should be CFRelease?

    EDIT: After looking up Get Rule and Create Rule, I think I now understand that it is exactly what you meant. Perhaps a reference should be maintained and then CFRelease'd. So, instead of the original:
    NSMutableArray *peopleArray = [[(NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook) autorelease] mutableCopy];
    it should be more like:
    CFArrayRef *peopleRef = ABAddressBookCopyArrayOfAllPeople(addressBook) ;
    NSMutableArray *peopleArray = [(NSArray *)peopleRef mutableCopy];
    // Do stuff with peopleArray
    [peopleArray release];  // could have been autorelease on mutableCopy above
  6. macrumors 65816


    Because, and only because, a CFArray is toll-free bridged to an NSArray, you can use autorelease or release on it. But normally, yes, for a Core Foundation type you need to call the CFRelease function (or a more more specialised release function for the type).

Share This Page