Any和AnyObject区别

Any vs AnyObject

将项目里的 AnyObject 转成 Any 在swift3可能大家会有点困惑,在swift2 我们可以写完一个项目都只用 AnyObject 来代表大多数实例,好像不用与 Any 类型打交道。但事实上,Any 和 AnyObject 是有明显区别的,因为 Any 可以代表 struct、class、func 等等几乎所有类型,而 AnyObject 只能代表 class 生成的实例。

你可能会有点疑惑我们在 Swift 2 里可以用 [AnyObject] 声明数组,并且在里面放 Int、String 等 struct 类型呢?这是因为 Swift 2 中,会针对这些 Int、String 等 struct 进行一个 Implicit Bridging Conversions,在 Array 里插入他们时,编译器会自动将其 bridge 到 Objective-C 的 NSNumber、NSString 等类型,这就是为什么我们声明的 [AnyObject] 里可以放 struct 的原因

但在 Swift 3 当中,为了达成一个门真正的跨平台语言,相关提案将 Implicit Bridging Conversions 给去掉了。所以如果你要把 String 这个 struct 放进一个 [AnyObject] 里,一定要 as NSString,这些转换都需要显示的进行了——毕竟 Linux 平台默认没有 Objective-C runtime。这样各平台的表现更加一致。当然这是其中一个目标,具体可见 0116-id-as-any 和相关提案的讨论。
以及objective id to swift Any See: Developer

看看Any和AnyObject到底是什么

Any是一个空协议集合的别名,它表示没有实现任何协议,因此它可以是任何类型,包括类实例与结构体实例。Any是一个别名。
AnyObject是一个成员为空的协议,任何对象都实现了这个协议。
AnyClass是AnyObject.Type的别名而已。
下面看一下Any的声明,在Swift中:

typealias Any = protocol<>```

下面看一下AnyObject的定义:
@objc protocol AnyObject {
}
这个协议未定义任何成员。@objc是一个声明特性,该特性用于修饰任意可以在ObjC中访问或使用的声明,比如非嵌套类,协议,类和协议中的属性和方法,初始化器,析构器,以及下标。如果你将objc特性应用于一个类或协议,它也会隐式地应用于那个类或协议的成员。对于标记了objc特性的类,编译器会隐式地为它的子类添加objc特性。
AnyObject使用@objc声明特性修饰,是因为它要做为Objc与Swift混编的使者,两者传递变量很多类型便是AnyObjct。
不同于Any,AnyObject是一个没有声明任何成员的空协议,是Any表示一个空的协议集合。AnyObject是一个协议,Any是零个协议

OC id map changes
![](media/14943326749280/123.png)


###Implicitly Unwrapped Optionals 的坑

在 Swift 2 的项目中,我们可能存在这样不是特别安全的代码:
var greetings: String!
greetings = "Hello"
print("\(greetings) 啊哈哈")

这里会输出:
Hello 啊哈哈

没有任何问题。但是在 Swift 3 中,因为 Optional 的安全机制起作用了,会变成:
Optional("Hello") 啊哈哈

这个结果不是我们想要的。从这点也可以看到,Swift 3 的 IUO(隐式解包可选(ImplicitlyUnwrappedOptional)
 Swift的类型设计本能十分安全) 行为变得更安全了,默认会把 IUO 变成 Optional。如果想要达到和 Swift 2 一样的效果,就得用:

print("\(greetings!)  啊哈哈")
这时你也注意到了,Swift 始终在用 ! 提醒你用 IUO 不那么安全。

你可能感兴趣的:(Any和AnyObject区别)