Objective-C中的方法语法


176

有人可以为我解释此方法声明语法吗?在此功能中,将返回UIPickerView(iPhone上的老虎机UI)的行数。据我了解,该方法称为“ pickerView”,并返回一个NSInteger。

它首先传入一个名为' pickerView' 的UIPickerview指针,为什么该方法与参数同名?

接下来是称为组件的NSInteger参数,该参数告诉我们我们要为哪个组件计数行。确定该方法主体中的逻辑。

什么是' numberOfRowsInComponent?它似乎描述了我们要返回的值,但它位于参数的中间。

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

    return[self.zips count];
}

Answers:


358

Objective-C方法旨在自我记录,并且借鉴了Smalltalk的丰富传统。

我将尽力解释您在这里的情况-(NSInteger) pickerView:(UIPickerView*)pickerView numberOfRowsInComponent:(NSInteger)component

  • - (NSInteger)
    第一部分表明这是一个返回NSInteger对象的Objective C 实例方法。的-(短划线)表示这是一个实例的方法,其中+将指示这是一种方法。括号中的第一个值是方法的返回类型。

  • pickerView:
    这部分是消息名称的一部分。在这种情况下,完整的消息名称pickerView:numberOfRowsInComponent:。Objective-C运行时将使用此方法信息,并将其发送到指定的接收器。在纯C中,这看起来像
    NSInteger pickerView(UIPickerView* pickerView, NSInteger component)。但是,由于这是Objective-C,因此其他信息将打包到消息名称中。

  • (UIPickerView*)pickerView
    这部分是输入的一部分。此处的输入为类型,UIPickerView*并且具有局部变量名称pickerView。

  • numberOfRowsInComponent:
    这部分是消息名称的第二部分。如您在此处看到的,消息名称被拆分以帮助指示您要传递给接收者的信息。因此,如果要向对象myObject传递变量foo和bar,我将输入:
    [myObject pickerView:foo numberOfRowsInComponent:bar];
    ,而不是C ++样式:
    myObject.pickerView(foo, bar);

  • (NSInteger)component
    这是输入的最后一部分。这里的输入是类型,NSInteger并且具有组件的局部变量名称。


18
+1是个不错的答案。我建议您在第一点将“工厂”更改为“类”,因为“ +”正式表示类方法。碰巧很多“ +”方法都是工厂方法,但这不是正确的定义。
e.James 2009年

2
谢谢!另一个问题:如果要向对象myObject传递变量foo和bar,如显示的那样:[myObject pickerView:foo numberOfRowsInComponent:bar]; pickerView是否引用方法名称或参数?
Craig

2
都不行 最好同时引用方法名称和参数,但是完整的方法名称实际上是pickerView:numberOfRowsInComponent:。如果尝试调用pickerView :,则将收到运行时错误,因为该方法将不存在。
locriani

1
让我澄清一下:pickerView:部分本身应该引用以下参数,以遵循良好的编码样式。但是,它只是方法名称的1/2。更好的示例可能是[myObject setX:foo Y:bar],其中方法是setX:Y:。
locriani

1
我知道这个答案很旧,但是过去几年我一直生活在.NET世界中。我是Objective C的新手,正在从网络世界过渡到移动行业。我要感谢您提供了一个与问题非常相关的有据可查的解释。+1
d3v1lman1337

52

在Objective-C中,方法的名称由声明的所有非参数和类型部分组成。因此,该方法的名称为:

pickerView:numberOfRowsInComponent:

该方法等效于C样式的函数,如下所示:

编辑:(感谢Jarret Hardie):

NSInteger pickerViewNumberOfRowsInComponent(UIPickerView * pickerView, NSInteger component)

1
+1-简短的简短说明。有时,如果您将C样式的等效代码写为“ NSInteger pickerViewNumberOfRowsInCompoent(UIPickerView * pickerView,NSInteger组件)”,我发现灯泡会持续点亮人们
Jarret Hardie,2009年

我喜欢您的解释,用C重写会更好。
lcc 2014年

30

除了前面的答案,我想说的是Objective-C方法(或消息,如果您愿意)具有外部内部参数名称。

因此,在这种情况下:

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

numberOfRowsInComponent外部名称,从外部调用此方法时将使用的名称。

并且component是参数的内部名称,您可以使用它从方法内部引用该参数。

希望能将其清除。


1
根据您的描述,方法名称可以视为第一个参数的外部名称。这也符合wilczarz的下面的评论。
杰克

该死,我发现这个答案太不正确了。没有什么像参数的外部/内部名称一样。它的类型和变量标识符。我想知道为什么每个人都这么努力地将ObjC定义为自然语言,而在所有方面都是如此不自然。它是一种语言,也就是它,它使您无需学习任何花哨的单词就可以学习它。
悉达多

参数可以具有内部/外部名称。确实如此。
lcc 2014年

21

在我看来,Objective-C方法签名更像是句子。每个参数都应在方法名称中占一部份。例如,在C语言中,我们可以有一个方法(setPersonData)来设置有关人员的一些信息:

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

并且在Objective-C中,该方法将更具描述性(setPersonName:andAge:andHeight:),例如

- (void) setPersonName: (char *)name andAge:(int)age andHeight:(float)height {

8
为什么setPersonalData(char * andName,int AlsoAge,float AlsoHeight)没有意义?这全都与您对语法的了解有关,而与objc设计人员的聪明意图无关。他们只是添加了一堆坦率地说没有任何意义的语法..::)
Siddharth

5
恐怕您误解了答案。setPersonalData(char * andName,int AlsoAge,float AlsoHeight)是签名,而不是调用。该函数的调用将是setPersonData(“ Tom”,25,175)-但这还不多呢?Obj-C调用如下所示:[person setPersonName:@“ Tom” andAge:25 andHeight:175];
wilczarz 2013年

3
现在我考虑了一下,我的回应更多是抱怨而不是陈述。我完全同意。
2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.