【问题标题】:Swift: EXC_BAD_ACCESS calling a method from a generic type that implements a protocolSwift:EXC_BAD_ACCESS 从实现协议的泛型类型调用方法
【发布时间】:2016-08-19 03:13:01
【问题描述】:

我正在使用 Swift 2 和 Xcode 7.3 开发一个项目,但遇到了一个我还不明白原因的错误。

我创建了一个名为 Resource 的协议,它有一个 associatedtype 和一个 static var 类型。

在其扩展中,我正在尝试创建static var 的getter 的默认实现,其中类型是通用struct,它实现另一个protocol,称为ResourceFinderProtocol

这一切都编译得很好,但是在运行时,当执行下面 sn-p 的最后一行时,它会产生 EXC_BAD_ACCESS 崩溃。

如果我使struct ResourceFinder 不是通用的,它会顺利运行。

protocol Resource {
    associatedtype ResourceFinderType
    static var localObjects: ResourceFinderType { get }
}

extension Resource {
    static var localObjects: ResourceFinder<Self> {
        return ResourceFinder()
    }
}

public protocol ResourceFinderProtocol {
    associatedtype ResourceType
    func all() -> [ResourceType]
}

struct ResourceFinder<T:Resource>: ResourceFinderProtocol {
    func all() -> [T] {
        return []
    }
}

struct Model: Resource {}

Model.localObjects.all()

对这里可能发生的事情有什么想法吗?

编辑:

正如 Alexander 指出的那样,即使我将调用拆分为:

let localObjects = Model.localObjects
let allObjects = localObjects.all()

...它仍然在第一行崩溃。

【问题讨论】:

  • 顺便说一句,Model.localObjects 也崩溃了。

标签: swift generics swift2 protocols


【解决方案1】:

这是一个编译器错误,在访问localObjects 属性时导致堆栈溢出。据我所知,这是您的类型之间递归依赖的问题,更具体地说,localObjects 是通过动态调度调用的。如果我从Resource 中删除static var localObjects: ResourceFinderType { get },它就可以工作。

或者,如果您从ResourceFinder 中删除Resource 约束,它也会成功运行。

我已经报告了这个问题,你可以通过SR-1314跟踪它

【讨论】:

  • 感谢您报告问题,Stuart。他们已经将其标记为已解决,因为它似乎已固定在 master 上。所以这个修复会在下一个版本中出现。
  • 我确认它也适用于 04-25 3.0 SNAPSHOT
猜你喜欢
  • 2020-03-15
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多