views:

69

answers:

3

Hi,

I have a set of classes that were created by www.sudzc.com (awesome WDSL web service proxy creation tool for iPhone/Flex/Javascript).

When I run the CMD+SHIFT+A to check for memory leaks I get the following message:

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

Here is the method that it is returning that message for:

// Static method for initializing from a node.
+ (id) newWithNode: (CXMLNode*) node
{
    return (id)[[[SoapObject alloc] initWithNode: node] autorelease];
}

I don't want to message with this code and it will need to be regenerated many times through the project, as the web services change and I need to update the proxy classes.

Any ideas?

Thanks in advance.

Jason

A: 

The method is flagged because the method name has the 'new' prefix. The static analyzer is just commenting that applying normal method naming conventions one would expect that method to return an object that you are meant to release, and not an autoreleased object.

The "normal" naming convention for methods such as that is to prefix the method with the name of the class, for example if that method was defined for a class called Widget:

@interface Widget : NSObject {
}
+ (id)widgetWithNode:(CXMLNode*)node; // Returns an object that has been autoreleased.
- (id)initWithNode:(CXMLNode*)node; // Returns an object you are expected to release.
@end

If you're using the method correctly (that is, you're accounting for the fact that it returns an autoreleased object) then you can just ignore that warning.

imaginaryboy
Hi Imaginaryboy,Thanks for your response! It is appreciated!I ended up changing the name of the method.Thanks!Jason
JasonBub
+2  A: 

The analyzer is complaining because the memory management guide dictates that...

You “create” an object using a method whose name begins with “alloc” or “new” or contains “copy”'.

Cocoa and Objective-C rely heavily on convention, you should make every effort to follow that. Turn on "treat warnings as errors" and fix the problem. While you may be the only person working on this now, if at any point another developer were to use your methods, it is likely they would follow the memory management guidelines, and end up over-releasing the object returned by this method (and crashing the app).

Jerry Jones
This is exactly right. If you want to return an autoreleased object, then rename the function. You could try `+createWithNode:` instead. Otherwise, get rid of that autorelease and rely on the caller to autorelease it instead.
Kevin Ballard
Hi, Jerry/Kevin, thanks for this information. It is appreciated!Based on Jerry's recommendation, I have done a Global Search and Replace for newWithNode and replaced it with createWithNode. I recompiled and everything worked fine.Now, I need to remember to do this whenever I generate an updated set of proxy classes using the http://www.sudzc.com wsdl generation tool.Thanks again!
JasonBub
A: 

If you have a method name that has to have something like "new" or "copy" in it, and you know the warning is invalid - you can eliminate the warning by including a hint to LLVM that the class is really OK.

In your header file, first add this (usually near the top but it could be anywhere):

#ifndef __has_feature      // Optional.
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
#endif

#ifndef NS_RETURNS_NOT_RETAINED
#if __has_feature(attribute_ns_returns_not_retained)
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
#else
#define NS_RETURNS_NOT_RETAINED
#endif
#endif

Then at the end of your method declaration add like so:

+ (id) newWithNode: (CXMLNode*) node NS_RETURNS_NOT_RETAINED;

You can find a list of other hints (really attributes) that you can pass to LLVM here:

http://clang-analyzer.llvm.org/annotations.html

Kendall Helmstetter Gelner
You can certainly do this, but it'll be confusing to anybody else who comes along and looks at this code, because they'll be assuming that a method named +newWithNode: is supposed to return an owned object. This trick is more useful for things like -dataNoCopyForColumn: (taken from FMDB) which erroneously triggers the warning based on the "copy" in the name.
Kevin Ballard
Hi Kendall, Thanks for the excellent information on how to tweak the LLVM. This is really cool. I ended up changing the method name. But, will also try this method out for my internal knowledge base.Thanks again!Jason
JasonBub
@Kevin - I did say when the name HAD to have new or copy - in this context, you are talking about method names generated from a WSDL which is describing server side calls, and often you have no power as a consumer of that service to rename the methods. But I agree that if possible, a method name like that would be pretty confusing to an objc programmer! So much so I'd wrap it in some other call that all the other code in the app used.
Kendall Helmstetter Gelner