为什么Swift让我在AnyObject上调用setTitle?

问题描述:

@IBAction func helloClick(sender: AnyObject) { 

    sender.setTitle("Click", forState: UIControlState.Normal) 

} 

上面的代码工作正常。但setTitle不是AnyObject上的方法吗?这不应该是一个编译时错误?为什么Swift让我在AnyObject上调用setTitle?

这是语言规范的一部分(见id compatibility部分)

您也可以拨打任何Objective-C的方法和访问任何财产(在AnyObject),而不强制转换为更具体的类类型。

这是为了更容易实现Objective-C互操作。

指南还指出以下:

但是,由于分型为AnyObject对象的特定类型是未知的,直到运行时,有可能在无意中写不安全的代码。

显然,由于代码的有效性只在运行时确定,因此这可能是不安全的。

+0

编译器确实知道'setTitle2'例如不存在,它不会编译它。所以它不会让我写不安全的代码。 – 2014-09-19 14:26:47

+0

当然,它会让你编写不安全的代码。它会让你编写'(NSArray()as AnyObject).setTitle(“foo”,forState:.Normal)'几乎肯定会崩溃。同样,给出你的示例代码,它会让你调用'helloClick(NSArray())',这会产生类似的效果。任何时候你使用AnyObject都是不安全的,除非你总是首先确保你提出的操作是安全的。通常通过适当地将它转换为更具体的东西。 – 2014-09-19 15:54:02

+2

@IanWarburton:您可以调用任何方法名称,其中有一个@ objc'方法声明,并且该名称对于编译器可见。您使用方法名称“setTitle:”导入了一个API,但它从未见过任何具有方法名称“setTitle2:”的类。如果你用名为'setTitle2:'的'@ objc'方法声明一个类,那么是的,它会编译它。 – newacct 2014-09-19 18:25:09

AnyObject行为类似于Objective-C的id

它允许它被调用的任何方法。 AnyObject的目的是绕过编译时错误。你可以调用AnyObject上的任何方法,它会很好地编译。您只会在运行时看到错误。

%的文档,

您也可以拨打任何Objective-C的方法,并没有强制转换为更具体的类类型访问任何财产(在AnyObject)。