Swift 从类型初始化对象时出现编译器段错误
Swift Compiler SegFault when initializing Object from Type
我目前正在使用 Swift 开发 iOS 应用程序。我有一个自定义数据源,需要知道它必须提供的模型类型。我有一个自定义协议,它有一种方法。
protocol JSONModel {
init(json: JSON)
}
然后,有几个模型实现了协议。它们都具有不同的属性,但其他方面相同。
class CurrentDownload: JSONModel {
let someProperty: String
required init(json: JSON) {
someProperty = json["someProperty"].stringValue
}
}
我的数据源有一个 属性 类型 JSONModel.Type
private let modelClass: JSONModel.Type
当我尝试初始化我的 modelClass 的新实例时,出现分段错误。模型的初始化由
完成
let model = modelClass(json: modelJSON)
不幸的是,编译器在那一行崩溃了。
Swift Compiler Error
Command failed due to signal: Segmentation fault: 11
1. While emitting IR SIL function
@_TFC14pyLoad_for_iOS21RemoteTableDataSourceP33_56149C9EC30967B4CD75284CC9032FEA14handleResponsefS0_FPSs9AnyObject_T_ for 'handleResponse' at RemoteTableDataSource.swift:59:13
有没有人知道如何解决这个问题或如何解决这个问题?
我相信这道题并不难。
通常 Swift 分段错误是当您尝试设置常量 (let) 的值,或尝试设置未正确声明的值时。
我可以在这里发现一个这样的例子:
required init(json: JSON) {
bytesLeft = json["someProperty"].stringValue
}
这个例子有两处错误。您有一个(指定的)初始化程序,它在不设置 属性 someProperty 的情况下终止,并且您还没有声明变量 bytesLeft.
所以现在的问题(我 确实 之前应该发现)是 * modelClass* 不是 class(或其他可初始化类型)。不能直接访问协议,只能访问符合协议的class。编译器没有发现这一点,因为你用 .Type.
做了一些偷偷摸摸的事情
当我说访问时,我指的是函数和属性,包括初始化程序。
只有 class 可以创建 class 的实例,它以自身作为实例的类型,协议本身不能有真正的实例。
如果你仔细考虑一下,就不可能很好地定义你想在这里做什么。假设我们有协议
protocol JSONModel {
init(json: JSON)
}
然后 两个 classes:
class CurrentDownload: JSONModel {
let someProperty: String
required init(json: JSON) {
//Some other code perhaps.
someProperty = json["someProperty"].stringValue
}
}
class FutureDownload: JSONModel {
let differentProperty: String
required init(json: JSON) {
//Different code.
differentProperty = json["differentProperty"].stringValue
}
}
而之前有人可能会争辩说
JSONModel.Type(json: JSON)
(此代码等同于您的代码)应该编译并且 运行 因为我们已经给出了 init 的实现,我们现在不能否认有混淆 - 我们应该在这里使用哪个实现?它不能选择一个,大多数人会争辩说它不应该尝试,所以它没有。
你需要做的是初始化一些class。
如果您正在寻找符合 JSONModel 的最小 class 而不是更多,则需要编写这样的 class 例如
class BasicJSONModel: JSONModel {
let someProperty: String
required init(json: JSON) {
//Some other code perhaps.
someProperty = json["someProperty"].stringValue
}
}
然后做
private let modelClass: BasicJSONModel//.Type not needed with a class
let model = modelClass(json: modelJSON)
当然,这可能很愚蠢,可能只写
let model = BasicJSONModel(json: modelJSON)
或者 如果协议的唯一用途是这样的话,你可以写一个通用的 superclass:
class SuperJSONModel {
let someProperty: String//This is not needed of course and you could just strip down to the init only.
init(json: JSON) {
//Some other code perhaps.
someProperty = json["someProperty"].stringValue
}
}
然后你想检查某个对象是 "conforming" 到什么是 JSONModel,你只需检查它是一个子 class SuperJSONModel.
我目前正在使用 Swift 开发 iOS 应用程序。我有一个自定义数据源,需要知道它必须提供的模型类型。我有一个自定义协议,它有一种方法。
protocol JSONModel {
init(json: JSON)
}
然后,有几个模型实现了协议。它们都具有不同的属性,但其他方面相同。
class CurrentDownload: JSONModel {
let someProperty: String
required init(json: JSON) {
someProperty = json["someProperty"].stringValue
}
}
我的数据源有一个 属性 类型 JSONModel.Type
private let modelClass: JSONModel.Type
当我尝试初始化我的 modelClass 的新实例时,出现分段错误。模型的初始化由
完成let model = modelClass(json: modelJSON)
不幸的是,编译器在那一行崩溃了。
Swift Compiler Error
Command failed due to signal: Segmentation fault: 11
1. While emitting IR SIL function
@_TFC14pyLoad_for_iOS21RemoteTableDataSourceP33_56149C9EC30967B4CD75284CC9032FEA14handleResponsefS0_FPSs9AnyObject_T_ for 'handleResponse' at RemoteTableDataSource.swift:59:13
有没有人知道如何解决这个问题或如何解决这个问题?
我相信这道题并不难。
通常 Swift 分段错误是当您尝试设置常量 (let) 的值,或尝试设置未正确声明的值时。
我可以在这里发现一个这样的例子:
required init(json: JSON) {
bytesLeft = json["someProperty"].stringValue
}
这个例子有两处错误。您有一个(指定的)初始化程序,它在不设置 属性 someProperty 的情况下终止,并且您还没有声明变量 bytesLeft.
所以现在的问题(我 确实 之前应该发现)是 * modelClass* 不是 class(或其他可初始化类型)。不能直接访问协议,只能访问符合协议的class。编译器没有发现这一点,因为你用 .Type.
做了一些偷偷摸摸的事情当我说访问时,我指的是函数和属性,包括初始化程序。 只有 class 可以创建 class 的实例,它以自身作为实例的类型,协议本身不能有真正的实例。 如果你仔细考虑一下,就不可能很好地定义你想在这里做什么。假设我们有协议
protocol JSONModel {
init(json: JSON)
}
然后 两个 classes:
class CurrentDownload: JSONModel {
let someProperty: String
required init(json: JSON) {
//Some other code perhaps.
someProperty = json["someProperty"].stringValue
}
}
class FutureDownload: JSONModel {
let differentProperty: String
required init(json: JSON) {
//Different code.
differentProperty = json["differentProperty"].stringValue
}
}
而之前有人可能会争辩说
JSONModel.Type(json: JSON)
(此代码等同于您的代码)应该编译并且 运行 因为我们已经给出了 init 的实现,我们现在不能否认有混淆 - 我们应该在这里使用哪个实现?它不能选择一个,大多数人会争辩说它不应该尝试,所以它没有。
你需要做的是初始化一些class。 如果您正在寻找符合 JSONModel 的最小 class 而不是更多,则需要编写这样的 class 例如
class BasicJSONModel: JSONModel {
let someProperty: String
required init(json: JSON) {
//Some other code perhaps.
someProperty = json["someProperty"].stringValue
}
}
然后做
private let modelClass: BasicJSONModel//.Type not needed with a class
let model = modelClass(json: modelJSON)
当然,这可能很愚蠢,可能只写
let model = BasicJSONModel(json: modelJSON)
或者 如果协议的唯一用途是这样的话,你可以写一个通用的 superclass:
class SuperJSONModel {
let someProperty: String//This is not needed of course and you could just strip down to the init only.
init(json: JSON) {
//Some other code perhaps.
someProperty = json["someProperty"].stringValue
}
}
然后你想检查某个对象是 "conforming" 到什么是 JSONModel,你只需检查它是一个子 class SuperJSONModel.