Было много проблем с протоколами Swift в сочетании с массивами, но я даже не мог воспроизвести всю свою проблему до того, как все стало ломаться на детской площадке. Вот минимальный пример.Объявление соответствия протоколу @objc в пустых разрывах расширений с EXC_BAD_INSTRUCTION
У меня есть два протокола и класс Bus
, который декларирует соответствие одному из протоколов. Кроме того, пустое расширение Bus
заявляет о соответствии с другим протоколом:
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
Выход консоли может выглядеть случайным образом, но это не так. Я получаю это последовательно, если я пытаюсь создать экземпляр Bus
:
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.
- ошибка исчезнет, если мы закомментируйте все
@objc
атрибуты - ошибка уходит, если мы не соответствуют
Utterable
:extension Bus
: Utterable
{}
причина, почему мои протоколы MUST имеют атрибут @objc
, потому что в противном случае среда выполнения Obj-c будет жаловаться при попытке сделать что-то вроде var myDisplayables: [Displayable] = [ Bus() ]
или иначе динамически проверять на соответствие протоколу
Снова обратите внимание, что это минимальный пример.
Обновление с помощью Swift 1.2: Похоже, что оно исправлено. Xcode предлагает эти изменения «так как протокол требует»:
class Bus : Displayable { @objc var name = "a bus"; @objc var utterance = "this is a bus"}