此处的错误处理感觉不对。有人建议如何改进吗?使用可选绑定来建立错误和返回值变量。
那很酷?class ChargePointsFetcher {
func getDevices(location: NSURL, completion handler:([ChargeDevice]?, error: NSError?) -> Void) {
let request = NSURLRequest(URL: location)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request, completionHandler: { (let data, let response, let error) -> Void in
var returnValue: NSError?
if let e = error {
returnValue = e
}
var collection: [ChargeDevice]?
if returnValue == nil {
collection = [ChargeDevice]()
var parsingError: NSError?
if let json: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: &parsingError) as? NSDictionary {
if let chargeDevices = json.valueForKey("ChargeDevice") as? NSArray {
for chargeDevice in chargeDevices {
let device = ChargeDevice()
collection!.append(device)
}
}
}
if let e = parsingError {
returnValue = e
}
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
handler(collection, error: returnValue)
})
})
}
}
答案 0 :(得分:1)
在我看来,你应该尽可能地避免使用(Value?, Error?)
模式。由于两种组合是非法的,因此会产生坏的角落情况相反,如果可能的话,我建议(Value, Error?)
任何时候Value
都有明智的“零”。在这种情况下,“零”是“空阵列”。这非常接近地匹配ObjC意义,因为nil
NSArray非常类似于空数组。
这样做,您可以大大简化此代码:
func getDevices(location: NSURL, completion handler:([ChargeDevice], error: NSError?) -> Void) {
// Note that error is marked "var" so we can modify it, and switched from NSError! to NSError?
let task = session.dataTaskWithRequest(request, completionHandler: { (let data, let response, var error: NSError?) -> Void in
var result = [ChargeDevice]()
if error == nil {
// Avoid NSArray and NSDictionary wherever you can in Swift
if let
json = NSJSONSerialization.JSONObjectWithData(data,
options: .AllowFragments,
error: &error
) as? [String:AnyObject],
chargeDevices = json["ChargeDevice"] as? [AnyObject] {
// map is much simpler in this case, but in your full code, for may fine fine
result = chargeDevices.map{ _ in ChargeDevice() }
}
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
handler(result, error: error)
})
})
}
请注意,在您的代码和我的代码中,不正确但有效的JSON不会产生任何类型的错误。它会悄悄跳过as?
次来电。我可能会将所有这些JSON工作移动到另一个函数中,以防止这个闭包失控。
此处的另一种方法称为Result
。我的首选示例是Rob Rix's。虽然我已经在Result
做了很多工作,但我个人觉得很难干净地与Cocoa联系起来。如果您的整个程序使用它,并且如果您封装了大多数Cocoa交互,那么它很有用,但我发现使用它作为一次性解决方案很麻烦。 (很多人在这里不同意我,这只是我的经验。Result
绝对值得探索以形成自己的观点。)