let f: () -> Void = { }
let array = ["a", 1, false, f] as [Any]
if array[3] is AnyObject {
print(array[3])
}
为什么AnyObject的元素评估为true,即使数组设置为存储Any?
为什么函数作为AnyObject求值为true,即使AnyObject按定义只能是类?
另一个例子:
let f: () -> Bool = { return true }
let ff = f as AnyObject
(ff as () -> Bool)()
这违反了API doc中AnyObject的定义,其中声明:
AnyObject可以用作任何实例的具体类型 类,类类型或仅类协议。
或官方Swift Programming Language Guide:
•Any可以代表任何类型的实例,包括函数 类型。
•AnyObject可以表示任何类类型的实例。
在上面的例子中,看起来函数可以表示为AnyObject。
在SO的其他地方有解释(由@hamish指出),因为在内部使用SwiftValue类,任何东西都可以桥接到AnyObject。解释的逻辑似乎是有缺陷/反向的,因为我们应该使实现符合语言定义,而不是相反,所以要么实现不正确,要么AnyObject和typecheck运算符的定义不正确?
答案 0 :(得分:1)
首先,Swift编程语言指南不是ISO 9899定义C的语言规范。(即使给出了ISO标准,并非每个编译器都实现相同的C,甚至100%符合标准。如果您发现编译器和文档之间存在分歧,那么作为编译器错误的文档错误就很可能。
那就是说,我相信你已经掩盖了你引用的规范的一个重要部分:
AnyObject也可以用作桥接到Objective-C类的类型实例的具体类型。 Swift中的许多值类型桥接到Objective-C对应物,如String和Int。
() -> Void
相当于dispatch_block_t
,它与dispatch_object
(见dispatch/object.h
和os/object.h
)的ObjC相连:
/*
* By default, dispatch objects are declared as Objective-C types when building
* with an Objective-C compiler. This allows them to participate in ARC, in RR
* management by the Blocks runtime and in leaks checking by the static
* analyzer, and enables them to be added to Cocoa collections.
* See <os/object.h> for details.
*/
OS_OBJECT_DECL_CLASS(dispatch_object);
因此,() -> Void
可以强制转换为AnyObject
,这并不奇怪。
在实践中,几乎任何现在可以桥接到AnyObject
(同样,从语言规范的角度来看,任何可以是NSValue
的内容都可以是AnyObject
{1}},即使这不完全是如何实现的。)
AnyObject
与Any
不同。 Any
表现得像一个协议(尽管不是协议)。 AnyObject
的行为类似于每个类的超类(尽管实际上是一个协议)。
let b = true // true
let bany = true as Any // true
let banyobj = true as AnyObject // 1 <=== (because it's NSNumber)
MemoryLayout.size(ofValue: b) // 1 (size of a bool)
MemoryLayout.size(ofValue: bany) // 32 (size of a protocol box)
MemoryLayout.size(ofValue: banyobj) // 8 (size of a reference pointer)
type(of: b) // Bool.Type
type(of: bany) // Bool.Type
type(of: banyobj) // __NSCFBoolean.Type
(对{}
尝试相同的事情,看看如何处理闭包。)
合理地针对AnyObject
文档打开一个缺陷,以包含更明确的解释,即任何类型都可以使用as AnyObject
转换为引用类型,但这只是一个遗漏,而不是一个已经存在的矛盾。 (如果它是一个矛盾,或者你发现它令人困惑,那么,正确的答案是打开一个缺陷来改进文档以匹配Swift,而不是Swift来匹配文档。)