Question

Running a static analysis with clang in both XCode 3.2 and Nikita Zhuk's Analysis Tool I've often come across this pair of warnings:

Method returns an Objective-C object with a +0 retain count (non-owning reference)

Incorrect decrement of the reference count of an object is not owned at this point by the caller

An example of code that may provoke this warning:

UIButton* button = [[UIButton buttonWithType:UIButtonTypeCustom] initWithFrame: CGRectMake(x, y, width, height)];
return button;

I assumed that buttons created this way are autoreleased, just like any other NSObject created with a convenience factory method. So I return it, and the caller can decide whether to retain it or not. What's the problem with that?

Am I obliged to retain and autorelease the object before returning it? And most importantly, could whatever this warning is warning against ever be the cause of scary release-related crashes?

I realize now that this seems to only occur with UIButtons. Is it due to it being a class cluster?

EDIT: The snipped below shows a minimal case where clang issues these warnings (with the warnings in bold). Both warnings are flagged on the statement creating the object (the buttonWithType: message).

-(UIButton*) ztupidTezt:(UIImage*) img
{
  UIButton* bt = [[UIButton buttonWithType:UIButtonTypeCustom]initWithFrame:

1 Method returns an Objective-C object with a +0 retain count (non-owning reference)

2 Incorrect decrement of the reference count of an object is not owned at this point by the caller

    CGRectMake(0.0f, 0.0f, img.size.width, img.size.height)];
    bt setImage:img forState:UIControlStateNormal];
    return bt;
}
Was it helpful?

Solution

The cause is most likely the use of sending both a buttonWithType: and initWithFrame: message. init* methods perform tasks that should only be done once for a given object. Class methods that create objects also initialize them. The result of your code is repeated initialization. Instead, send the buttonWithType message, then assign to the frame property.

OTHER TIPS

Well.... that code makes no sense.

buttonWithType: returns an instance of a UIButton that is already initialized. You shouldn't be calling -initWithFrame: on it.

Call setFrame:.

The bad code is confusing the analyzer.

Secondly, why bother with a third party tool to do the analysis. If you are using Xcode 3.2 on Snow Leopard (you should be -- it is a vastly better version of Xcode than the last release on Leopard), you can just "build and analyze". All of the analysis results will be presented inline with your code quite nicely.

Does the method name that has this code within it have "new" as a prefix? The Clang Static Analyzer follows standard Cocoa naming conventions and assumes that a -newSomething method will return an instance with a retain count of 1. If it's seeing an autoreleased object being returned from such a method, it might present the warning you're seeing.

Old, old, question. I am having the same problem. I think the existing answers successfully explained why the code is wrong, and why the analyzer says "+0 retain count". However it doesn't look like anybody explained why the analyzer says the code is decrementing the retain count. I think i figured out why. It's because of how init methods are allowed to return a different object than you sent the message to. They would release the original object, alloc a new one, and return it. The analyzer is assuming that any init method could do such a thing, although the init method in this example might not.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top