当我使用
Any类型进行编写时,例如在处理JSON数据时,在项目中花费了相当长的时间。 但我也知道还有第二种类型
-AnyObject 。 最近,我一直在思考这两种类型之间的区别。
根据Apple文档:
为了简单起见,然后:
让我们在实践中验证这两种类型。 让我们从类型
Any开始。
为此,创建一个类型为Any的数组,然后打印它。
let anyArray: [Any] = ["Macbook", 1, 2] print(anyArray) Console: ["Macbook", 1, 2]
如我们所见,Any允许您同时处理不同类型的数据(字符串,整数)。
根据文档,此数组中的元素(
String和
Int )是值类型的结构,因此,从理论上讲,
AnyObject不起作用。
要验证这一点,请创建一个类型为
AnyObject的相同数组。
let anyObjectArray: [AnyObject] = ["Macbook", 1, 2]
不出所料,编译器向我们显示了一个错误,即无法将类型“ String / Int”转换为类型
AnyObject编译器错误无法将类型“ Int”的值转换为预期的元素类型“ AnyObject”
无法将类型“ Int”的值转换为预期的元素类型“ AnyObject”
无法将类型“字符串”的值转换为预期的元素类型“ AnyObject”
但是,让我们尝试将这三种类型引入AnyObject并打印结果。
let anyObjectArray: [AnyObject] = ["Macbook" as AnyObject, 1 as AnyObject, 2 as AnyObject] print(anyObjectArray) Console: [Macbook, 1, 2]
编译器错误已消失。 如我们所见,
Macbook字符串显然看起来像字符串,但是没有通常的引号,如Swift中的
String类型。
让我们尝试使用循环来打印数组以检查其实际类型。
for item in anyObjectArray { if item is String { print("\(item) String") } else if item is Int { print("\(item) Int") } } Console: Macbook String 1 Int 2 Int
字符串的类型为字符串。 如前所述,Swift中的字符串是结构,而不是类的类型。 因此,我们不应将它们用作AnyObject。
让我们对数组进行更多的实验。 让我们尝试检查它们是否包含Objective‑C中的类型:
NSString和
NSNumber 。
for item in anyObjectArray { if item is NSString { print("\(item) NSString") } else if item is NSNumber { print("\(item) NSNumber") } } Console: Macbook NSString 1 NSNumber 2 NSNumber
那么为什么会这样呢?
作为与Objective-C兼容性的一部分,Swift提供了使用Cocoa平台的便捷有效的方法。
Swift将自动将某些Objective-C类型转换为Swift类型,并将某些Swift类型转换为Objective-C类型。 可以在Objective-C和Swift之间转换的类型称为
串联 。
换句话说,编译器通过自动转换和创建“桥”来尽一切可能灵活地处理这些类型,同时防止应用程序崩溃。
什么时候使用AnyObject?
如Apple文档中所述,AnyObject可用于处理
从Class派生但没有公共根类的对象。
在Swift 3中,现在将Objective-C中的id类型映射到Swift中的Any类型,该类型描述了任何类型的值,无论是类,枚举,结构还是其他任何Swift类型。 这项更改使Objective-C API在Swift中更加灵活,因为可以将Swift定义的值类型传递给Objective-C API并作为Swift类型进行检索,从而无需手动的“块”类型。
因此,
建议您在要限制协议时
使用 AnyObject ,以便仅可用于类,而
在其他情况下可使用
Any 。
苹果补充说 :
仅当您明确需要它们提供的行为和功能时,才使用
Any和
AnyObject 。 始终最好对要在代码中使用的类型保持精确。