Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I fix this clang warning: "Object with +0 retain counts returned to caller where +1 (owning) retain count is expected"?

I have a piece of Objective-C code that looks like the following:

- (NSString *)copyData:(NSData *)data
{
    NSString *path = [[[self outputDirectory] stringByAppendingPathComponent:@"archive"] stringByAppendingPathExtension:@"zip"];
    NSLog(@"Copying data to %@", path);
    [data writeToFile:path atomically:NO];
    return path;
}

The code is called from an initializer that looks like this:

- (id)initWithData:(NSData *)data
{
    if ((self = [super init]) != nil) {
        NSString *path = [self copyData:data];        // Line 41 (referenced in warning, shown below)
        return [self initWithContentsOfFile:path];
    }
    return self;
}

When running the clang static analyzer, I get the following warnings for the path variable:

Potential leak of an object allocated on line 41 and stored into 'path'

Object with +0 retain counts returned to caller where +1 (owning) retain count is expected

I'm confused. My understanding is that stringByAppendingPathComponent should return an autoreleased string, so it should have a net retain count of 0. (Obviously I don't want to retain it.)

I've tried altering copyData: to return the following, but it didn't get rid of the warning:

return [[path retain] autorelease];

So what's the deal with this warning?

like image 364
mipadi Avatar asked May 14 '10 22:05

mipadi


2 Answers

I suspect it's just noticing a method with the prefix copy and flagging that as something that should return something that the caller owns, because it thinks it's following Cocoa naming conventions.

In your case, of course, you are referring to files and whatnot, so it's an ignorable warning. If you change the name of your method, to something like saveData: instead, I bet the warning will go away.

like image 199
Ben Zotto Avatar answered Nov 22 '22 05:11

Ben Zotto


Also, for times where you really do want to name a method with 'copy' or something because regardless of Cocoa memory management guidelines, copy is the best name for the method, you can annotate the method declairation with NS_RETURNS_NOT_RETAINED and then Clang won't give you a warning. So:

// Copies data from data to string; does not follow the copy rule
- (NSString*)copyData:(NSData*)data NS_RETURNS_NOT_RETAINED;
like image 43
Jason Coco Avatar answered Nov 22 '22 04:11

Jason Coco