Добавление дополнительной информации к уже отличным ответам.
Я создал три программы и посмотрел на сгенерированной сборки из каждого:
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)
T различия между obj1 и obj2 тривиальны. Любые инструкции, которые включают тип объекта имеют разные значения:
movq %rax, __Tv3obj3objCS_7MyClass(%rip)
# ...
globl __Tv3obj3objCS_7MyClass .globl __Tv3obj3objPs9AnyObject_
.zerofill __DATA,__common,__Tv3obj3objCS_7MyClass,8,3
# ...
.no_dead_strip __Tv3obj3objCS_7MyClass
против
movq %rax, __Tv3obj3objPs9AnyObject_(%rip)
# ...
.globl __Tv3obj3objPs9AnyObject_
.zerofill __DATA,__common,__Tv3obj3objPs9AnyObject_,8,3
# ...
.no_dead_strip __Tv3obj3objPs9AnyObject_
Полный дифференциал here.
Это было интересно для меня. Если единственными различиями между этими двумя файлами являются имена типа объекта, почему объект, объявленный как 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 here.
isKindOfClass
выслан как динамически отправленный метод, см. _objc_msgSend
. Оба объекта подвергаются Objective-C как SwiftObject
(.quad _OBJC_METACLASS_$_SwiftObject
), объявляя тип объекта как AnyObject
, завершает мост до NSObjectProtocol
.
Но 'AnyObject' определяется как' @objc public protocol AnyObject {} 'Означает ли это, что все протоколы' @ objc' соответствуют 'NSObjectProtocol'? Как насчет 'Любые'? – JAL
Это совсем не значит. Я говорю то, что я говорю, а не что-то другое. – matt
Вы говорите, что «необоснованный класс, такой как MyClass, невозможно». Так вы говорите, что «MyClass» наследует «SwiftObject»? Почему только листинг в 'AnyObject' выставляет соответствие NSObjectProtocol? – JAL