无法暗示 _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 逻辑不在其中记录内容。
我正在阅读 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 逻辑不在其中记录内容。