Thanks to the iPhone and the growth of the Mac there are a lot of people now interested in Objective-C and Cocoa. Many of these developers come from other backgrounds such as Python, Ruby, C#, C++, Java etc, but Objective-C is quite a different beast to those languages.
Of course there are quite a few similarities. It shares the C heritage of C++, it is highly dynamic like Python and Ruby. However, the biggest difference between Objective-C and most other languages is how method names and arguments interact.
At first glance a lot of developers coming from other languages think that they are simply named arguments which is wrong, VERY wrong. This is one of my pet peeves about new Objective-C developers, and every time I see someone talking about named arguments in Objective-C I always feel a need to correct them. But if they aren't named arguments then what are they?
The arguments aren't named, but interspersed with the method name. For example, a method in another language may be obj.foo(namedArg1=bar, namedArg2=possum), so its method name is foo. In Objective-C a similar method may be [obj foo:bar with:possum]. In this case the method name is foo:with:. So the arguments aren't named, they are mixed in with the method name.
There are some key differences between named arguments and interspersed arguments:
1) Named arguments' names are not part of the method name
2) Named arguments can be re-arranged
3) Named arguments are often optional
None of these hold true for interspersed arguments. This is why I've seen quite a few people complain about Objective-C's "named arguments" not being very flexible. When you realise they aren't named then things get much easier to understand. As with everything in Cocoa and Objective-C, if it is different to what you are used to, then there is likely a very good reason for it being that way.
So it would make sense to show some examples comparing named and interspersed arguments. So lets take a common Objective-C method:
[@"A string" compare:@"B string" options:NSCaseInsensitiveSearch range:someRange];
And now lets convert it to a language like Python which has named argument, treating the arguments as named arguments:
"A string".compare("B string", options=NSCaseInsensitiveSearch, range=someRange);
Not a big difference at first, but lets try some variations:
"A string".compare("B string", range=someRange, options=NSCaseInsensitiveSearch);
"A string".compare("B string", options=NSCaseInsensitiveSearch);
In Python those are both the same method as the first one. However, in Objective-C, re-arranging the arguments or removing them would result in an entirely different method being called. While in the Python examples the method is called compare() in the Objective-C example it is called -compare:options:range: which is a big difference. If we correctly treat the arguments as interspersed then the Python example becomes:
"A string".compare_options_range("B string", NSCaseInsensitiveSearch, someRange);
Of course Python doesn't support interspersed arguments so they are all attached at the end, but basic rules are the same. Hopefully this has helped quite a few Objective-C newbies to understand one of the many differences between it and other languages they are used to, but if you have any questions then leave them in the comments.
Correction: in [foo:bar with:possum], the method name is foo:with:, not -foo:with:. The instance/class distinction is not relevant to method name.
Hey, it’s a nitpicky topic.
Oops, fixed :p I first thought that it had the distinction as you can have class and instance methods with the same name, but now I think about it they go to different objects so there’s no reason to have a distinction.
The Python form via PyObJC would have a trailing _.
That is, compare_options_range_(...)
PyObjC chose that particular convention as it is absolutely dead simple and completely unambiguous.
(When I saw “The Named Argument”, I got scared… then I read the post… much better.
Thankyou for that—started learning last night, & that’s a potential world of confusion avoided!
Doug.
A great post indeed. Even some Apple developers can’t explain it as clear as you do here. Thanks!