EXC_BAD_ACCESS在Swift中使用generics

相关的问题: 在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 } 

符合Entity每个对象实现init(json: JSON)JSON是SwiftyJSON库中定义的一种types。 这也是枚举看起来有点奇怪的原因。

我用这个方法调用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) } } 

我得到了一个调用T(json: subJSON)错误EXC_BAD_ACCESS(code=EXC_I386_GPFLT)错误。 没有编译器警告或错误。 虽然我没有在上面的代码中检查错误,但在实际的代码中有错误检查, 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)" } } 

该代码在子类中使用self.init(json: json)进行编译,但实际上试图使用便捷方法初始化实例导致EXC_BAD_ACCESS

要么删除子类上的初始化器,要么简单地实现required init和超级调用。

 class EntitySub: EntityBase { required init(json: JSON) { super.init(json: json) } override func getName() -> String { return "Sub with \(name)" } } 

jsonData转换为Entity (当jsonData niljsonData修改以.None jsonData ):

 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 }