在这些优秀的答案中,我希望添加一些额外的信息。
我创建了三个程序,并查看了每个程序生成的汇编代码:
obj1.swift
import Foundation
class MyClass { }
let obj = MyClass()
obj2.swift
import Foundation
class MyClass { }
let obj: AnyObject = MyClass()
obj3.swift
import Foundation
class MyClass { }
let obj: AnyObject = MyClass()
obj.isKindOfClass(MyClass.self)
obj1和obj2之间的差异微不足道。任何涉及对象类型的指令都具有不同的值:
movq %rax, __Tv3obj3objCS_7MyClass(%rip)
# ...
globl __Tv3obj3objCS_7MyClass .globl __Tv3obj3objPs9AnyObject_
.zerofill __DATA,__common,__Tv3obj3objCS_7MyClass,8,3
# ...
.no_dead_strip __Tv3obj3objCS_7MyClass
vs
movq %rax, __Tv3obj3objPs9AnyObject_(%rip)
# ...
.globl __Tv3obj3objPs9AnyObject_
.zerofill __DATA,__common,__Tv3obj3objPs9AnyObject_,8,3
# ...
.no_dead_strip __Tv3obj3objPs9AnyObject_
完整的差异请点击这里.
我觉得这很有趣。如果两个文件之间唯一的区别是对象类型的名称,为什么声明为AnyObject
的对象可以执行Objective-C选择器?
obj3展示了如何触发isKindOfClass:
选择器:
LBB0_2:
# ...
movq __Tv3obj3objPs9AnyObject_(%rip), %rax
movq %rax, -32(%rbp)
callq _swift_getObjectType
movq %rax, -8(%rbp)
movq -32(%rbp), %rdi
callq _swift_unknownRetain
movq -24(%rbp), %rax
cmpq $14, (%rax)
movq %rax, -40(%rbp)
jne LBB0_4
movq -24(%rbp), %rax
movq 8(%rax), %rcx
movq %rcx, -40(%rbp)
LBB0_4:
movq -40(%rbp), %rax
movq "L_selector(isKindOfClass:)"(%rip), %rsi
movq -32(%rbp), %rcx
movq %rcx, %rdi
movq %rax, %rdx
callq _objc_msgSend
movzbl %al, %edi
callq __TF10ObjectiveC22_convertObjCBoolToBoolFVS_8ObjCBoolSb
movq -32(%rbp), %rdi
movb %al, -41(%rbp)
callq _swift_unknownRelease
xorl %eax, %eax
addq $48, %rsp
# ...
LBB6_3:
.section __TEXT,__objc_methname,cstring_literals
"L_selector_data(isKindOfClass:)":
.asciz "isKindOfClass:"
.section __DATA,__objc_selrefs,literal_pointers,no_dead_strip
.align 3
"L_selector(isKindOfClass:)":
.quad "L_selector_data(isKindOfClass:)"
obj2和obj3之间的差异请这里查看。
isKindOfClass
被发送为动态调度方法,如_objc_msgSend
所示。两个对象都以SwiftObject
(.quad _OBJC_METACLASS_$_SwiftObject
)的形式暴露给Objective-C,将对象类型声明为AnyObject
完成了到NSObjectProtocol
的桥接。
AnyObject
被定义为@objc public protocol AnyObject { }
,这是否意味着所有的@objc
协议都符合NSObjectProtocol
?那Any
呢? - JALMyClass
继承自SwiftObject
吗?为什么只有将其转换为AnyObject
才能暴露出符合NSObjectProtocol
的内容? - JALisKindOfClass
实际上也作为动态分派消息发送了吗? - mz2