Presumably this is because deepCopy does not start with the copy prefix.
So you might want to change something like copyWithDeepCopiedValues (or something like that) and then see if the analyzer indicates this.
Update
As noted by Aleksander, you can use attributes to indicate the purpose of link counting. This should (IMO) be the exception to the rule and be rarely, if ever, used. Personally, I will not use attributes for objc methods, because it is fragile.
The only attribute I have used so far has been consume , and every time I use these attributes, it was in statically typed contexts (e.g. C functions and C ++ functions and methods).
Reasons you should avoid attributes when possible:
1) Stick to conventions for programmers. The code is more understandable, and you do not need to refer to the documentation.
2) This approach is fragile. You can still introduce a link counter imbalance, and attributes can be used to introduce assembly errors due to conflicts in the attributes.
All versions are built with ARC enabled:
Case No. 1
#import <Foundation/Foundation.h> @interface MONType : NSObject - (NSString *)string __attribute__((objc_method_family(copy))); @end @implementation MONType - (NSString *)string { NSMutableString * ret = [NSMutableString new]; [ret appendString:@"MONType"]; return ret; } @end int main (int argc, const char * argv[]) { @autoreleasepool { id obj = nil; if (random() % 2U) { obj = [[NSAttributedString alloc] initWithString:@"NSAttributedString"]; } else { obj = [MONType new]; } NSLog(@"Result: %@, %@", obj, [obj string]); } /* this tool name is ARC, dump the leaks: */ system("leaks ARC"); return 0; }
This program throws the following error: error: multiple methods named 'string' found with mismatched result, parameter type or attributes .
Great, the compiler does everything possible to prevent these problems. This means that conflicts in attributes can introduce translation-based errors. This is bad because when non-trivial code bases are combined and attribute conflicts, you will have errors to fix and update programs. It also means that simply including other libraries in translation units can violate existing programs when using attributes.
Case No. 2
header.h
extern id NewObject(void);
Header.m
#import <Foundation/Foundation.h> #import "Header.h" @interface MONType : NSObject - (NSString *)string __attribute__((objc_method_family(copy))); @end @implementation MONType - (NSString *)string { NSMutableString * ret = [NSMutableString new]; [ret appendString:@"-[MONType string]"]; return ret; } @end id NewObject(void) { id obj = nil; if (random() % 2U) { obj = [[NSAttributedString alloc] initWithString:@"NSAttributedString"]; } else { obj = [MONType new]; } return obj; }
main.m
Ok This is just bad . We introduced leaks because the necessary information was not available in the translation block. Leaks reported here:
leaks Report Version: 2.0 Process 7778: 1230 nodes malloced for 210 KB Process 7778: 4 leaks for 192 total leaked bytes. Leak: 0x1005001f0 size=64 zone: DefaultMallocZone_0x100003000 __NSCFString ObjC CoreFoundation mutable non-inline: "-[MONType string]" Leak: 0x100500320 size=64 zone: DefaultMallocZone_0x100003000 __NSCFString ObjC CoreFoundation mutable non-inline: "-[MONType string]" Leak: 0x100500230 size=32 zone: DefaultMallocZone_0x100003000 has-length-byte: "-[MONType string]" Leak: 0x100500390 size=32 zone: DefaultMallocZone_0x100003000 has-length-byte: "-[MONType string]"
note: the score may be different because we used random()
This means that since MONType does not appear in main() , the compiler binds the ARC properties to methods that were visible to the current TU (i.e., string from declarations in Foundation, all of which follow the convention). As a result, the compiler made a mistake, and we were able to inject leaks into our program.
Case 3
Using a similar approach, I was also able to introduce negative imbalances in the counts (premature releases or exchange zombies).
note: The code is not specified, because Example 2 already illustrates how to unbalance the reference counter.
Conclusion
You can avoid all these problems and improve readability and support by adhering to the agreement rather than using attributes.
Message return to non-ARC code: using attributes simplifies manual memory management for easier reading by programmers and for tools that can help you (for example, compiler, static analysis). If the program is complex enough so that the tools cannot detect such errors, then you should review your design, because it will be difficult for you or someone else to debug these problems.