6
votes

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

3

3 Answers

12
votes

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).

5
votes

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.

0
votes

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