在将 Swift 协议与数组结合使用时遇到了很多麻烦,但在操场上开始出现问题之前,我什至无法重现我的整个问题。这是一个最小的例子。
我有两个协议和一个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
{}
我的协议必须具有该属性@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"}