简体   繁体   中英

Retain count and factory methods in Objective-C

I have been in this forum before to find the best way of creating a factory function to construct a custom view from a nib ( here is my previous post)

i am now using the following code:

+ (LoadingV *)loadingViewCopyFromNib 
{   
    LoadingV *view = nil;   
    NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"LoadingV" owner:self options:nil];
    view = (LoadingV*)[nibViews objectAtIndex: 0];

    // Setting up properties
    CGRect frm = view.progress.frame;
    frm.size.width *=1.5;
    frm.size.height *=1.5;
    view.progress.frame = frm;
    view.waitLbl.text = NSLocalizedString(@"Please wait", @"");     
    return view;    <------- warning is here
}

// In .h file
...
LoadingView* loadV;
@property (nonatomic, retain) LoadingView* loadV;

// in .m file
@synthesize loadV;
...
self.loadV = [LoadingV loadingViewCopyFromNib];

When i Build and Analyse i get the following warning about the factory function:

/LPAPP/Classes/LoadingV.m:34:5 Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected

Why is this happening? I understand that local variables allocated within a function do not live beyond its scope unless they are retained and autoreleased. But in my case i am not creating a new object am just returning a reference to an existing one. So why am i getting warning back? Is it safe to proceed like this :)

Cheers AF

Although Mike is right, the warning has a completely different reason. Your method name includes "copy" which is interpreted to return a +1 retain count (similar to alloc, init). Remember that once you transition to ARC this may cause problems!

When it comes to collection classes like NSArray , references returned by objectAtIndex: and other similar accessors are not guaranteed to stay valid when the parent container is deallocated. In other words, objectAtIndex: does not return an autorelease'd object.

This means the pointer you return will probably end up becoming invalid once the array it came from is deallocated.

To fix this, use a retain + autorelease in your return statement:

return [[view retain] autorelease];

UPDATE:

I'm unable to reproduce this warning in my version of Xcode. But perhaps Martin is correct that the 'copy' is being interpreted incorrectly by the version of GCC/clang that you are using. This warning doesn't appear with the latest Xcode and gcc/clang compilers, and the rules are that only a prefix of "copy" or "mutableCopy" is interpreted as returning a +1 retained object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM