Clang: what is "Method returns an Objective-C object with a +0 retain count" trying to tell me?

Felixyz picture Felixyz · Oct 2, 2009 · Viewed 7.1k times · Source

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;
}

Answer

bbum picture bbum · Oct 2, 2009

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.