首先,一些上下文:在回答关于SO的问题时,我遇到了一个帖子,其中作者一直试图设置一个语法类似于[self.propertyGetter:newValue];
的getter。由于某种原因,这编译,我想,“这将构成对零的呼吁,不是吗?”。所以,我的问题是,为什么这个“工作”呢? (很明显,海报抱怨这没有效果,所以“工作”,我的意思是编译)。
答案 0 :(得分:3)
您引用的代码是[self.propertyGetter:newValue]
。以下是Objective-C编译器解析它的方法。
左括号之后的第一件事必须是消息的接收者。在该代码中,接收器是self.propertyGetter
的值。编译器将self.propertyGetter
转换为[self propertyGetter]
。因此,我们可以将您引用的代码重写为[[self propertyGetter]:newValue]
。
现在编译器需要找出消息的选择器。您通常会看到一个关键字选择器,例如setStatusBarHidden:animated:
,这是一系列关键字后跟冒号。但事实证明,关键字可以是零长度。因此冒号本身就是一个有效的关键字选择器。所以编译器看起来像这样:[[self propertyGetter] :newValue]
。 (使用零长度关键字几乎总是非常糟糕的风格。)
您可以使用该选择器声明实例方法。例如:
- (void):(NSObject *)newValue;
如果[self propertyGetter]
返回具有该方法的类的对象,则代码将编译并运行。
如果编译器看到任何类的方法名为this,而[self propertyGetter]
返回类型id
,则代码将编译(因为id
是一个通配符类型,如果您尝试发送任何已知消息选择器,编译器将不会抱怨。但是,如果[self propertyGetter]
实际上无法理解:
消息,则应用会在运行时崩溃。
答案 1 :(得分:1)
这是编译,因为默认情况下所有的Objective-C对象都是动态实体。它会编译,但会在运行时崩溃。