Reputation: 6566
One of the things I like most about Cocoa is the readability factor.
One of the things that annoys me the most is the convention of convenience constructors to force repetition.
Here's an example:
[NSString stringWithString:s]
[NSNumber numberWithDouble:d]
[NSValue valueWithInt:i]
[NSDictionary dictionaryWithObjectsAndKeys:<blah>]
etc.
Why doesn't the convention simply start convenience constructors with the word "with"? so then we would have:
[NSString withString:s]
[NSNumber withDouble:d]
[NSValue withInt:i]
[NSDictionary withObjectsAndKeys:<blah>]
etc.
It's a minor discussion point, but one I thought I would just throw out there and see if anyone with more clout than me can explain all the echos in my head.
Obviously, I'm not going to petition AAPL to re-write the appKit in favour of my suggestion, but are there any arguments against naming my own convenience constructors as such?
Of course I can use whatever conventions I want in my own code but I hate to swim upstream blindly.
Upvotes: 8
Views: 638
Reputation: 107754
Ultimately, I believe the Objective-C philosophy, as embodied by the Cocoa frameworks (and the NextStep frameworks before it) is that being explicit, and easy to maintain takes precedence over terseness of code. The main evidence for this philosophy is that Objective-C selectors have named arguments (e.g. -[NSObject performSelector:withObject:]
).
In the case of factory methods such as +[NSString stringWithString:]
, you must remember that subclasses may override these class methods to return subclasses (for example class clusters such as NSNumber
).
So, you may end up with a call like [MyPoorlyNamedSubclass stringWithString:]
in which case -[MyPoorlyNamedSubclass withString:]
would not be obviously informative as to the type of object returned (recall that many factory methods return type id
). stringWithString:
, on the other hand makes it clear that the method will return a string (or subclass thereof).
Upvotes: 3
Reputation: 6081
They also use that one extra word to tell if the object is autoreleased or not. initWithFormat is for non-autoreleased, and when its stringWithFormat it is autoreleased... I guess they just went with that way of telling the reader what kind of memory management the object uses...
Upvotes: 2
Reputation: 237040
There is actually a technical reason for it to be that way. If every shoelaceWithString:
-type method were changed to just withString:
, we would end up with a fearsomely huge number of classes with identically named methods and different signatures. This plays mean tricks on the compiler's static type checking and can cause it to throw up all sorts of annoying and unnecessary warnings.
There's also an aspect of Cocoa culture where developers like their code to be self-documenting. This means that method names indicate both what their arguments are and what they return. Apple's coding guidelines actually warn about methods with vague names, suggesting that adding words to the name to make it clear what a method does is preferable.
Upvotes: 13
Reputation: 100110
Because it's consistent.
There are methods like:
[NSDictionary dictionary]
[NSArray array]
Getting rid of everything up to with
is obviously not an option here. Keeping these, but shortening others would introduce inconsistency in naming of convenience methods.
And convenience methods are consistent with init
and initWith…
methods.
Upvotes: 10
Reputation: 60498
I think it's just part of the general "say exactly what you mean" wordiness philosophy of the cocoa framework. A few choice selections:
[UIView setAnimationBeginsFromCurrentState]
[UITableView scrollToNearestSelectedRowAtScrollPosition]
[UIApplication didRegisterForRemoteNotificationsWithDeviceToken]
etc.
ETA:
To answer the questions specifically about constructors, one thing I like about the way they are done is that it's easy within x-code to identify which methods are constructor type methods. For example, you start typing:
[NSString string
And the "intellisense" whittles down the list of methods to those that start with "string" which of course are all the constructor methods (and all conveniently grouped together as well). Same thing applies for the "init" convention.
Upvotes: 3
Reputation: 58637
If you don't like it, why not write up a bunch of #define statements that you include in all your projects?
Upvotes: -2