9

I am tidying up my ancient Cocoa code to use modern naming conventions. There has been lots of discussion on best practices, but I'm unsure of one thing.

I'm thinking about adding a prefix to category method names, to ensure uniqueness. It seem generally agreed that this is a good idea, though most people probably don't bother.

My question is: what about a NSDictionary category method like -copyDeep that does a deep copy? The method used to be named -deepCopy, but I reversed the words as the analyzer looks for a prefix of "copy". Therefore I presumably couldn't add a prefix. And having the "prefix" in the middle or end of the method name seems messy and inconsistent.

I'd also be interested in thoughts on the style of prefix -- I currently use DS (for Dejal Systems) for class prefixes. But I know that Apple now wants to reserve all two-character prefixes for themselves, so am thinking about using Dejal, e.g. my class DSManagedObject would be renamed as DejalManagedObject. And getting back to categories, their methods would be renamed to add a dejal prefix, e.g. from -substringFromString: to -dejalSubstringFromString:. But -dejalCopyDeep would confuse the analyzer, so maybe I'd have to be inconsistent for such methods, and use -copyDeepDejal or -copyDeep_dejal?

I will be re-releasing my categories and various classes as open source once I've cleaned them up, so following the latest conventions will be beneficial.

Dejal
  • 813
  • 6
  • 18
  • 2
    good question! i'm curious about how you say apple wants to reserve two-char prefixes - i'm just wondering where you got that info from? when you create new projects it does suggest a 3 char prefix, but has there been an official statement on it? – Mike K Jan 07 '12 at 23:01
  • 1
    I can't find an official document that states that, but I believe it was mentioned in a [WWDC10 session on future-proofing](https://deimos.apple.com/WebObjects/Core.woa/BrowsePrivately/adc.apple.com.4092349126.04109539109.4144345635?i=2082492890). – Dejal Jan 07 '12 at 23:15
  • Revisiting this old question, I found documentation on the 3-char prefix recommendation, on the [Programming with Objective-C: Conventions](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html) page. – Dejal Jan 04 '15 at 20:12

2 Answers2

2

I emailed the Apple Application Frameworks Evangelist about this, and got a reply that recommended not prefixing category method names. Which conflicts with the advice in the aforelinked WWDC10 session, but I assume reflects Apple's current thinking.

He recommended just looking at the beta seed API diffs to spot conflicts, which is what I've always been doing.

Dejal
  • 813
  • 6
  • 18
1

I agree with Kevin Ballard, you should prefix your category method names, particularly if you are going to distribute them to others. But you do have a valid concern the analyzer will be confused by DScopy. The ARC compiler will similarly be confused if the definition/implementation of DScopy is done without ARC and is used by another class using ARC (or vice versa).

My preferred solution is to use "ownership transfer annotations", such as:

NS_RETURNS_NOT_RETAINED 
NS_RETURNS_RETAINED

They would be used to override the compilers default behavior of reading method names and acting on them. You might declare DScopy like so: (This declaration must be in a header file that is imported by all the classes that use this method mentioned due to link)

-(DSManagedObject *)DScopy; NS_RETURNS_RETAINED;

Source for NS_RETURNS... WWDC 2011 Session 322 - Objective-C Advancements in Depth. The meat of this issue begins at about time 9:10.

A note about "But I know that Apple now wants to reserve all two-character prefixes for themselves". As a personal preference I like to use the _ character to separate the prefix from the name, it works well for me. You might try something like:

-(DSManagedObject *)ds_copy; NS_RETURNS_RETAINED;

This would give you three characters, and arguably make the method name more readable.

Edit In response to link posted in comment.

However as Justin's answer to your original question says that can be broken.

With regards to attributes; I did not suggest using __attribute__((objc_method_family(copy))) I suggested using NS_RETURNS_RETAINED, which translates to :__attribute__((ns_returns_retained)). While the first example there won't even compile (as he says) using - (NSString *)string __attribute__((objc_method_family(copy))); it compiles with - (NSString *)string; NS_RETURNS_RETAINED; just fine.

Obviously also if the NS_RETURNS_.. are "hidden" from the compiler in separate the .ms or indirected in some other way and the compiler can't see the directives then it won't work. Because of this I would suggest putting the declaration for any methods that may cause the analyzer/compiler confusion in your main .h file (the one that imports all the others) to limit the chances that there will be an issue.

NJones
  • 27,139
  • 8
  • 70
  • 88
  • You might like to [read the comprehensive answer](http://stackoverflow.com/questions/7770872/deep-copy-of-dictionaries-gives-analyze-error-in-xcode-4-2) I got from @Justin when originally asking about my `deepCopy` method, which I renamed to `copyDeep` to fit with the naming conventions. But I am leaning towards using method prefixes in my categories, with `NS_RETURNS_RETAINED` for the few methods that need it. – Dejal Feb 11 '12 at 18:18
  • @Dejal Thanks for the link. I actually really did enjoy it. I updated my answer to be a little less dogmatic and respond in general. – NJones Feb 11 '12 at 19:43