存储 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.h
和 os/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
,尽管这并不是它的具体实现方式。
然而,AnyObject
与 Any
不同。 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 以匹配文档。)
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.h
和 os/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
,尽管这并不是它的具体实现方式。
AnyObject
与 Any
不同。 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 以匹配文档。)