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