Declarando conformidade com o protocolo @objc em quebras de extensão vazias com EXC_BAD_INSTRUCTION
Tenho tido muitos problemas com os protocolos Swift em combinação com matrizes, mas eu não conseguia nem reproduzir todo o meu problema antes que as coisas começassem a quebrar no playground. Aqui está um exemplo mínimo.
Eu tenho dois protocolos e uma classeBus
que declara conformidade com um dos protocolos. Além disso, uma extensão vazia deBus
declara conformidade com o outro protocolo:
import Foundation
@objc
protocol Displayable { var name: String {get} }
@objc
protocol Utterable { var utterance: String {get} }
class Bus : Displayable { var name = "a bus"; var utterance = "this is a bus"}
extension Bus : Utterable {}
var bus1 = Bus() // this line fails with EXC_BAD_INSTRUCTION
A saída do console pode parecer aleatória, mas não é. Eu o entendo de forma consistente se tentar criar uma instância deBus
:
objc[9658]: Method cache corrupted. This may be a message to an invalid object, or a memory error somewhere else.
objc[9658]: unused 0x0, SEL 0x10e4ce130, isa 0x1181f9ad0, cache 0x1181f9ae0, buckets 0x7fc491501060, mask 0x0, occupied 0x0
objc[9658]: unused 0 bytes, buckets 64 bytes
objc[9658]: selector 'resolveInstanceMethod:'
objc[9658]: isa '__lldb_expr_1314.Bus'
objc[9658]: Method cache corrupted.
O erro desaparece se comentarmos tudo@objc
atributosO erro desaparece se não estivermos em conformidade comUtterable
: extension Bus
: Utterable
{}
A razão pela qual meus protocolosdevo tem o atributo@objc
é porque, caso contrário, o tempo de execução do Obj-c reclamará ao tentar fazer coisas comovar myDisplayables: [Displayable] = [ Bus() ]
ou verificar dinamicamente a conformidade com um protocolo
Novamente, observe que este é um exemplo mínimo.
Atualize com o Swift 1.2: Parece que está consertado agora. O Xcode sugere essas alterações "porque o protocolo exige":
class Bus : Displayable { @objc var name = "a bus"; @objc var utterance = "this is a bus"}