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"}
答案 0 :(得分:1)
我认为问题是关于具有属性的Utterable
协议,该属性已在具体类中实现。
您可能知道,扩展无法定义存储的属性(仅计算)。通过在扩展中采用协议,发生了一些错误 - 这显然是一个错误(它应该只是或编译器应该引发编译错误)。
要修复它,只需在类声明中使用协议,而不是扩展名:
class Bus : Displayable, Utterable { var name = "a bus"; var utterance = "this is a bus"}
extension Bus {}
令人惊讶的是,将utterance
属性转换为计算属性并将其移动到扩展体中:
extension Bus : Utterable {
var utterance: String { return "this is a bus" }
}
没有解决问题 - 仍然是同样的错误。我认为这证明它是一个错误。