无法暗示 _Reflectable 协议

Fail to imply _Reflectable protocol

我正在阅读 nshipster 的 MirrorType,并试图将其代码采用到 Swift 2.1。一切正常,直到我尝试使用 :

自定义 _MirrorType
extension WWDCSession : _Reflectable {
    func _getMirror() -> _MirrorType {
       return WWDCSessionMirror(self)
    }
}

发生错误:

error: Playground execution aborted: Execution was interrupted, reason: EXC_BAD_ACCESS (code=2, address=0x7fff58273e87).

我发现这是因为 WWDCSessionMirror 中的 init 方法被无限次调用。

struct WWDCSessionMirror: _MirrorType {
private let _value: WWDCSession

init(_ value: WWDCSession) {
    _value = value
}

var value: Any { return _value }

var valueType: Any.Type { return WWDCSession.self }

var objectIdentifier: ObjectIdentifier? { return nil }

var disposition: _MirrorDisposition { return .Struct }

var count: Int { return 4 }

subscript(index: Int) -> (String, _MirrorType) {
    switch index {
    case 0:
        return ("number", _reflect(_value.number))
    case 1:
        return ("title", _reflect(_value.title))
    case 2:
        return ("track", _reflect(_value.track))
    case 3:
        return ("summary", _reflect(_value.summary))
    default:
        fatalError("Index out of range")
    }
}

var summary: String {
    return "WWDCSession \(_value.number) [\(_value.track.rawValue)]: \(_value.title)"
}

var quickLookObject: PlaygroundQuickLook? {
    print(summary)
    return .Text(summary)
}
}

我想问一下为什么会这样,如何解决?

_Reflectable 和 _MirrorType 不是您要找的机器人。

它们是遗留类型,已被 CustomReflectable(以及其他类型)取代。关于 LLDB 的 2015 WWDC session 对此进行了一些详细说明(免责声明:我是那部分的发言人 session,所以到处都是利益冲突:-)

但是,无论如何,您 运行 遇到的问题是因为这一行:

_value = value

由于您是在 playground 中键入此行,这会告诉 playground 逻辑捕获您正在分配的内容以供显示("log" 用 playground 的说法)。为此,playground 使用附加到该类型的 Mirror。因此,我们开始创建一个,这使我们 运行

_value = value

再次,这告诉游乐场逻辑记录值,这意味着我们创建一个镜像,...

您应该首先检查是否可以采用 Mirror 和 CustomReflectable 而不是 _MirrorType,以及使用这些 API 是否可以解决您的问题。如果不行,一个可能的解决方法是将反射支持代码放在一个辅助源文件中,这将导致 playground 逻辑不在其中记录内容。