wan*_*der 5 generics exc-bad-access ios swift
相关问题:Swift中的通用完成处理程序
在我写的Swift应用程序中,我正在下载JSON,我想将其转换为模型对象.现在,我这样做:
func convertJSONData<T: Entity>(jsonData: NSData?, jsonKey: JSONKey, _: T.Type) -> [T]? {
var entities = [T]()
if let data = jsonData {
// Left out error checking for brevity
var json = JSON(data: data, options: nil, error: nil)
var entitiesJSON = json[jsonKey.rawValue]
for (index: String, subJson: JSON) in entitiesJSON {
// Error: EXC_BAD_ACCESS(code=EXC_I386_GPFLT)
let entity = T(json: subJson)
entities.append(entity)
}
}
return entities
}
Run Code Online (Sandbox Code Playgroud)
每个对象符合Entity工具init(json: JSON).JSON是SwiftyJSON库中定义的类型.这也是枚举看起来有点奇怪的原因.
我打电话给convertJSONData()这个方法:
public func performJSONRequest<T where T: Entity>(jsonRequest: JSONRequest<T>) {
var urlString = ...
Alamofire.request(.GET, urlString, parameters: nil, encoding: .JSON).response { (request, response, data, error) -> Void in
var books = self.convertJSONData(data as? NSData, jsonKey: jsonRequest.jsonKey, T.self)
jsonRequest.completionHandler(books, error)
}
}
Run Code Online (Sandbox Code Playgroud)
我收到运行时EXC_BAD_ACCESS(code=EXC_I386_GPFLT)错误调用T(json: subJSON).没有编译器警告或错误.虽然我在上面的代码中省略了错误检查,但实际代码中存在错误检查,并且error为零.
我不确定这是一个编译器错误还是我的错,任何帮助搞清楚都非常感激.
这里发生了一些事情,我怀疑问题出在实现Entity协议的类的初始化程序中。
假设代码类似于以下内容:
protocol Entity {
init(json: JSON)
}
class EntityBase: Entity {
var name: String = ""
required init(json: JSON) { // required keyword is vital for correct type inference
if let nameFromJson = json["name"].string {
self.name = nameFromJson
}
}
func getName() -> String { return "Base with \(name)" }
}
class EntitySub: EntityBase {
convenience required init(json: JSON) {
self.init(json: json) // the offending line
}
override func getName() -> String { return "Sub with \(name)" }
}
Run Code Online (Sandbox Code Playgroud)
self.init(json: json)该代码在子类中编译,但实际上尝试使用便捷方法初始化实例会产生EXC_BAD_ACCESS.
要么删除子类上的初始值设定项,要么简单地实现required init并调用 super。
class EntitySub: EntityBase {
required init(json: JSON) {
super.init(json: json)
}
override func getName() -> String { return "Sub with \(name)" }
}
Run Code Online (Sandbox Code Playgroud)
将 the 转换jsonData为 an 的方法(稍微修改为在is时Entity专门返回): .NonejsonDatanil
func convertJSONData<T:Entity>(jsonData: NSData?, jsonKey: JSONKey, type _:T.Type) -> [T]? {
if let jsonData = jsonData {
var entities = [T]()
let json = JSON(data: jsonData, options:nil, error:nil)
let entitiesJSON = json[jsonKey.rawValue]
for (index:String, subJson:JSON) in entitiesJSON {
let entity:T = T(json: subJson)
entities.append(entity)
}
return entities
}
return .None
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
961 次 |
| 最近记录: |