180

Can someone explain this method declaration syntax for me? In this function, the number of rows of a UIPickerView (slot machine UI on the iPhone) is being returned. From my understanding, the Method is called 'pickerView', and returns an NSInteger.

It passes in a pointer to the UIPickerview called 'pickerView' ... first, why is the method called the same name as the parameter?

Next there is NSInteger parameter called component that tells us which component we are counting the rows for. The logic to decide which is in the body of the method.

What is 'numberOfRowsInComponent? It seems to describe the value we are returning, but it is in the middle of the parameters.

- (NSInteger) pickerView:(UIPickerView *)pickerView 
 numberOfRowsInComponent:(NSInteger)component
{
    if (component == kStateComponent)
        return [self.states count];

    return[self.zips count];
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Craig
  • 16,291
  • 12
  • 43
  • 39

4 Answers4

364

Objective-C methods are designed to be self documenting, and they borrow from the rich tradition of Smalltalk.

I'll try to explain what you have here, -(NSInteger) pickerView:(UIPickerView*)pickerView numberOfRowsInComponent:(NSInteger)component.

  • - (NSInteger)
    This first portion indicates that this is an Objective C instance method that returns a NSInteger object. the - (dash) indicates that this is an instance method, where a + would indicate that this is a class method. The first value in parenthesis is the return type of the method.

  • pickerView:
    This portion is a part of the message name. The full message name in this case is pickerView:numberOfRowsInComponent:. The Objective-C runtime takes this method information and sends it to the indicated receiver. In pure C, this would look like
    NSInteger pickerView(UIPickerView* pickerView, NSInteger component). However, since this is Objective-C, additional information is packed into the message name.

  • (UIPickerView*)pickerView
    This portion is part of the input. The input here is of type UIPickerView* and has a local variable name of pickerView.

  • numberOfRowsInComponent:
    This portion is the second part of the message name. As you can see here, message names are split up to help indicate what information you are passing to the receiver. Thus, if I were to message an object myObject with the variables foo and bar, I would type:
    [myObject pickerView:foo numberOfRowsInComponent:bar];
    as opposed to C++ style:
    myObject.pickerView(foo, bar);.

  • (NSInteger)component
    This is the last portion of the input. the input here is of type NSInteger and has a local variable name of component.

locriani
  • 4,995
  • 2
  • 23
  • 26
  • 19
    +1 for a great answer. I would suggest changing "factory" to "class" in your first point, since the "+" officially indicates a class method. It just so happens that many "+" methods are factory methods, but that isn't the proper definition. – e.James Mar 25 '09 at 20:26
  • 2
    Thanks! One additional question: If you were to message an object myObject with the variables foo and bar like you showed: [myObject pickerView:foo numberOfRowsInComponent:bar]; Does pickerView refer to the method name or parameter? – Craig Mar 25 '09 at 21:02
  • 2
    Neither. It is good style for it to refer to both the method name AND parameter, but the full method name is actually pickerView:numberOfRowsInComponent:. If you were to try to invoke pickerView:, you would recieve a runtime error, as the method would not exist. – locriani Mar 25 '09 at 21:13
  • 1
    Let me clarify on that: the pickerView: portion by itself SHOULD refer to the following parameter, to follow good coding style. However, it is only 1/2 of the method name. A better example may be [myObject setX:foo Y:bar], where the method is setX:Y:. – locriani Mar 25 '09 at 21:20
  • 1
    I know this answer is an old one, but I've been living in a .NET world for the past few years. I'm new to Objective C, and transitioning from a web world to the mobile industry. I'd like to thank you for such a well documented explanation that is so relevant to the question. +1 – d3v1lman1337 Sep 17 '12 at 15:24
  • If you'd like to read more please go here: https://xcodenoobies.blogspot.my/2017/07/how-to-basic-of-xcode-methods-functions.html – GeneCode Aug 18 '17 at 07:10
56

In Objective-C, the name of a method is composed of all of the portions of the declaration that are not arguments and types. This method's name would therefore be:

pickerView:numberOfRowsInComponent:

The method would be equivalent to a C-style function that looked as follows:

edit: (with thanks to Jarret Hardie):

NSInteger pickerViewNumberOfRowsInComponent(UIPickerView * pickerView, NSInteger component)
Community
  • 1
  • 1
e.James
  • 116,942
  • 41
  • 177
  • 214
  • 1
    +1 - nice short description. Sometimes I find the lightbulb goes on for people if you write the C-style equivalent as "NSInteger pickerViewNumberOfRowsInCompoent(UIPickerView *pickerView, NSInteger component) – Jarret Hardie Mar 25 '09 at 20:12
  • i like your explanation, to rewrite in C is much better. – lcc Jul 21 '14 at 15:53
33

Adding to the previous answers, I'd just like to say that Objective-C methods (or messages if you prefer) have external and internal parameter names.

So in this case:

- (NSInteger) pickerView:(UIPickerView *)pickerView 
 numberOfRowsInComponent:(NSInteger)component

numberOfRowsInComponent is the external name, the one that you would use when calling this method from the outside.

And component is the internal name of the parameter, the one you use to refer to the parameter from inside of the method.

Hope that clears it up a bit.

neonblitzer
  • 124
  • 1
  • 2
  • 10
Karolis
  • 879
  • 1
  • 9
  • 20
  • 1
    In accordance with your description, the method name could be considered as the external name of the first parameter. This also fits with wilczarz's comment bellow. – Jake Mar 25 '13 at 08:10
  • Damn, I find this answer so incorrect. There is nothing like a external / internal name of parameters. Its the TYPE and the VARIABLE identifier. I wonder why everyone try's so hard to define ObjC as a natural language, its just so unnatural in all its ways. Its a language, thats it, lets just learn it without using fancy words around it. – Siddharth May 24 '13 at 01:18
  • Arguments can have internal / external names. That's true. – lcc Jul 21 '14 at 16:05
21

It seems to me that Objective-C method signatures are more like sentences. Each parameter deserves a part in method's name. For instance, in C we could have a method (setPersonData) for setting some information about person:

void setPersonData( char* name, int age, float height ) {

and in Objective-C the method would be more descriptive (setPersonName:andAge:andHeight:), like

- (void) setPersonName: (char *)name andAge:(int)age andHeight:(float)height {
wilczarz
  • 343
  • 3
  • 7
  • 8
    And why would setPersonalData(char* andName, int alsoAge, float alsoHeight) not make sense ? Its all about what you understand about the syntax, nothing about the intention of objc designers being smart here. they just added a bunch of more syntax that frankly did not make any sense.. :) – Siddharth May 23 '13 at 18:34
  • 5
    You misunderstood the answer I'm afraid. setPersonalData(char* andName, int alsoAge, float alsoHeight) is a signature, not invocation. The invocation of this function would be setPersonData( "Tom", 25, 175 ) - and that doesn't say much does it? The Obj-C invocation would look like this: [person setPersonName: @"Tom" andAge: 25 andHeight: 175]; – wilczarz Dec 19 '13 at 15:24
  • 3
    Now that I think about it, my response is more a complaint than a statement. I couldn't agree more. – Siddharth Dec 19 '13 at 16:21
  • I like the ability to add the "external parameter names". This has been adopted by a lot of newer languages, but the syntax of spaces and colons REALLY was a regression from C as it doesn't distinguish between the name of the function and the inputs to that function :/ – Carson Holzheimer Mar 17 '21 at 02:59