存储 Any 对象的数组也是 AnyObject 类型

Array storing Any objects is also of AnyObject type

let f: () -> Void = { }

let array = ["a", 1, false, f] as [Any]

if array[3] is AnyObject {
  print(array[3])
}

即使数组设置为存储 Any,为什么元素对 AnyObject 的计算结果为真?

为什么函数作为 AnyObject 的计算结果为真,即使根据定义 AnyObject 只能是 classes?

再举个例子:

let f: () -> Bool = { return true }
let ff = f as AnyObject
(ff as () -> Bool)()

这违反了 API doc 中 AnyObject 的定义,该定义指出:

AnyObject can be used as the concrete type for an instance of any class, class type, or class-only protocol.

或官方Swift Programming Language Guide:

• Any can represent an instance of any type at all, including function types.

• AnyObject can represent an instance of any class type.

在上面的例子中,函数似乎可以表示为 AnyObject。

SO 中的其他地方有解释(正如@hamish 所指出的)在内部,因为使用了 SwiftValue class,所以任何东西都可以桥接到 AnyObject。解释的逻辑似乎是flawed/reverse,我们应该让实现符合语言定义,而不是相反,所以要么实现不正确,要么AnyObject和typecheck operator的定义不正确?

首先,Swift 编程语言指南不是 ISO 9899 定义 C 的语言规范。(即使给定一个 ISO 标准,并不是每个编译器都以相同的方式实现 C,甚至在 100 % 符合标准。)如果您发现编译器和文档之间存在分歧,那么它既可能是文档错误,也可能是编译器错误。

就是说,我相信您已经忽略了您引用的规范的重要部分:

AnyObject can also be used as the concrete type for an instance of a type that bridges to an Objective-C class. Many value types in Swift bridge to Objective-C counterparts, like String and Int.

() -> Void 等同于 dispatch_block_t,它作为 dispatch_object 连接到 ObjC(参见 dispatch/object.hos/object.h):

/*
 * 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,尽管这并不是它的具体实现方式。

然而,

AnyObjectAny 不同。 Any 表现得像一个协议(尽管不是协议)。 AnyObject 表现得像每个 class 的 superclass (尽管实际上是一个协议)。

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 以匹配文档。)