最近在项目中导入一个第三方库的时候遇到了一个bug,涉及到Any
和AnyObject
,查阅资料后发现在swift3中更新了一些使用方法,还是总结一下避免自己之后忘记。
首先简单介绍一下Any
和AnyObject
,套用喵神的话说,Any
和AnyObject
是swift中为了妥协而诞生的产物。我们都知道在OC中有一个叫id
的神奇的东西,它可以表示任意类的实例,看苹果现在的态度,虽然在大力推行swift,但是短时间内OC是不会消失的,所以两者必须协同发展,所以swift也必须有一个类似于id
的东西,否则两者相互调用的时候就会很混乱,于是乎就产生了Any
和AnyObject
。
对于Any
和AnyObject
,苹果官方给出的解释是:AnyObject
可以代表任意class
类型,而Any
则可以代表任意类型,包括函数类型。在swift3之前的版本中,id
被映射为AnyObject
,而在swift3中,id
被映射为Any
。这里有一个概念我比较迷惑,之前看过的一篇文章中有一段代码用来区分Any
和AnyObject
,是用swift2写的,代码如下:
func test(testObject object:Any) -> String {
if object is AnyObject {
return "传入的是一个引用(class)类型"
}
return "传入的是一个值类型"
}
/// 测试Block类型
let block = {
print("Hello World")
}
/// 测试元组
let http404Error = (404, "Not Found")
/// 测试数组
let array1:Array<Any> = []
let array2:Array<Int> = []
let array3:Array<AnyObject> = []
print(test(testObject: block))
print(test(testObject: http404Error))
print(test(testObject: array1))
print(test(testObject: array2))
print(test(testObject: array3))
而当我在swift3中测试的时候,打印出的结果都是“传入引用”。对应的,我们传入的参数分别是闭包,元组和数组,它们都应该是值类型。其中Xcode给出了一个警告:object is AnyObject is always true
.那么问题就应该出在这里。object
被声明为Any
,Any
is AnyObject
总是正确的,那么按照我个人的理解,Any
代表任何类型,其中就应该包括AnyObject
,当出现Any is AnyObject
的时候,Any
就会根据需要转换为AnyObject
,因此就会出现上述的警告。
最后回到自己项目的问题,按照库的作者提供的方法,需要实现cell
的一个自定义方法:
cell.rightUtilityButtons = getRightUtilityButtonsToCell()
rightUtilityButtons
是一个id
类型,在swift中被转换为Any
,getRightUtilityButtonsToCell()
方法返回一个NSMutableArray
类型的数组。这里报了一个错误,显示无法将NSMutableArray
类型赋值给[Any]!
类型,这里我的理解是:虽然Any
可以代表任何类型,但这是swift中的用法,代表的也应该是swift中的所有类型,而NSMutableArray
是一个OC类型,应该把它转换成swift类型,所以这里我们使用as
转换类型,代码更改为:
cell.rightUtilityButtons = getRightUtilityButtonsToCell() as [AnyObject]!
将NSMutableArray
类型转换为AnyObject
类型,这样就可以赋值成功,bug完美解决。
本文所表述的均是个人的一点浅薄的理解,如有错误的地方烦请各位看官不吝赐教。