Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ARC returning object from method best practice (getting memory leak warning)

I was creating a sample project in xcode 4.2 and noticed that the new project was setup with ARC.

I have a method shown below. Previously, I would have autoreleased the cell in the method and let the caller's table view retain the cell. With ARC, autoreleasing would not be possible,

- (UITableViewCell*) getCellForIndex:(int)index {

    UITableViewCell *cell =         
        [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];

    if (index == 0)
        cell.textLabel.text = profileToUse.name;
    if (index == 1)
        cell.textLabel.text = profileToUse.sex;
    if (index == 2)
        cell.textLabel.text = profileToUse.city;
    return cell;
}

When I running the analyze tool on the code above, it says that there is a potential memory leak of the object 'cell'.

How should the above be written using ARC so that the analyze warning will go away? What am I doing wrong?

Thanks.

like image 977
CF_Maintainer Avatar asked Jan 08 '12 18:01

CF_Maintainer


2 Answers

Try renaming the method to -cellForIndex:, "get"-prefixed methods have different implied behavior in Cocoa.

(Also, maybe -cellAtIndex: for consistency with NSArray, etc...)

like image 57
Catfish_Man Avatar answered Nov 09 '22 13:11

Catfish_Man


Your method getCellForIndex: allocates and returns an object, in this way it is similar to a straight alloc (indeed your code is just an alloc with some initialization).

As ARC does not see the actual implementation of a method when calling it must make an assumption about ownership of the returned object, and that assumption is that ownership is not transferred. When compiling your implementation ARC notices that your code violates this assumption and warns you.

The assumption can be overridden by adding an explicit attribute to your method in both the @interface and @implementation:

- (UITableViewCell*) getCellForIndex:(int)index __attribute((ns_returns_retained))

ARC will now know the object ownership is transferred. Methods in the alloc, new etc. families have this attribute added automatically. As other replies suggest you might be better off renaming your method, newCellForIndex: might be appropriate here as new is used for a combination of alloc and init which is what your method does.

BTW: Changing your second & third if's to else if's would make your algorithm clearer (and slightly faster, but that is not the reason to do it).

Question in comment:

ARC does introduce new attributes etc. but also uses inference and defaults so that if you follow normal Cocoa conventions you shouldn't need them too often - YMMV of course... In addition to Apple's docs you can find a description here.

like image 26
CRD Avatar answered Nov 09 '22 13:11

CRD