Reputation: 2458
I have a class like this
// a.swift
public class ComServiceString<Result>: ComService<Result> {
override func execute() {
if (method == Method.GET) {
manager.GET(getUrl(),
parameters: nil,
success: { (operation: AFHTTPRequestOperation!,responseObject: AnyObject!) in
self.onSuccessListener?(self.parseResult(responseObject.description))
},
failure: { (operation: AFHTTPRequestOperation!,error: NSError!) in
println("Error: " + error.localizedDescription)
var errorSd = ComServiceError(error.localizedDescription)
if (operation.response != nil) {
errorSd.errorCode = operation.response.statusCode
}
self.onFailedListener?(errorSd)
}
)
}
}
func parseResult(result: String) -> Result? {
fatalError("This method need to be implemented")
}
}
and I extend it to a new class like this
// b.swift:
public class BranchListService<T>: ComServiceString<BranchListModel> {
override func parseResult(result: String) -> BranchListModel? {
let branchListMode = BranchListModel(stringResult: result)
return branchListMode
}
}
my BranchListModel
looks like this
public class BranchListModel {
public var total = 0
public var stringResult = ""
init() {}
init (stringResult result: String) {
self.stringResult = result
if let jsonArray = JSONUtil.stringToJSONArray(result) {
if let resultObject = jsonArray[0] as? NSDictionary {
if let total = resultObject["total"] as? NSString {
self.total = total.integerValue;
}
}
}
}
}
but I got BAD_ACCESS
error in this line:
let branchListMode = BranchListModel(stringResult: self.resultString)
inside parseResult
function on b.swift
. I'm still learning this language with trying to convert my java
code to swift
. Do you guys know what's wrong from the code?
Upvotes: 1
Views: 296
Reputation: 2193
I think there is a bug of the Swift compiler. I've tested a relatively-simplified code below and that crashed in the same way.
class ResultParser<T> {
func parse(result: String) -> T? { abort() }
}
class MyResultParser<T>: ResultParser<Int> {
override func parse(result: String) -> Int? {
return result.toInt()
}
}
let parser: ResultParser<Int> = MyResultParser<()>()
parser.parse("2525")
At the moment, the Swift compiler cannot correctly treat virtual functions directly receiving and/or returning values, whose type is generic. I guess the compiler regards T
as a pointer (object) value whatever an actual substituted type is.
I've found a workaround to do nearly the same thing.
class Box<T> {
let raw: T
init(_ raw: T) { self.raw = raw }
}
class ResultParser<T> {
func parse(result: String) -> Box<T?> { abort() }
}
class MyResultParser<T>: ResultParser<Int> {
override func parse(result: String) -> Box<Int?> {
return Box(result.toInt())
}
}
In the code above, the returned value is wrapped in the Box<>
. Box<>
is an object, so that works no matter whether or not the compiler can tell value types from object types.
Upvotes: 1