Swift 2中明确的老式错误处理

6

苹果在Swift 2中引入了新的高级错误处理机制。

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html#//apple_ref/doc/uid/TP40014216-CH7-ID10

我正在处理一个使用AFNetworking v2.x的项目,其中AFHTTPRequestSerializer有两个选择器:

- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
                             URLString:(NSString *)URLString
                            parameters:(id)parameters DEPRECATED_ATTRIBUTE;

- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
                             URLString:(NSString *)URLString
                            parameters:(id)parameters
                                 error:(NSError * __autoreleasing *)error;

First 已经被弃用,但是 Swift 2 编译器会自动将第二个转换为第一个签名。现在不允许使用老式的方法:

var error: NSError?
let request = self!.operationManager.requestSerializer.requestWithMethod(method, URLString: url?.absoluteString, parameters: params, error: error)

给我一个编译时错误:

Cannot convert value of type 'NSError?' to expected argument type '()'

但是全新的符号表示法把带有错误处理的选择器降级为不带错误处理的过时变体。
do {
    let request = try
    self!.operationManager.requestSerializer.requestWithMethod(method, URLString: url?.absoluteString, parameters: params)
} catch let error as NSError {
    // ...
}

在Swift 2中,解决这个问题的最佳实践是什么?在这种情况下是否有指定特定选择器的方法?
更新:更精确地链接到导致我的问题的Swift 2功能。 https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html#//apple_ref/doc/uid/TP40014216-CH7-ID10

1
我知道我会怎么做;我会用Objective-C编写一个蹦床方法。(并向AFNetworking团队提交一个错误报告。) - matt
是的,如果Swift 2本身没有解决这个问题的工具,那么这似乎是一个更好的选择。但我想知道Swift的架构师是否预测到了这类问题,并且他们有一些适当的方法来克服这种类型的问题。 - lazarev
你确定已经调用了被弃用的变量吗?也许是Xcode混淆了弃用警告? - Sulthan
2个回答

0

在Xcode 7.1中似乎可以正常工作(我记得在7.0中存在此问题),只需更改您的方法以使用错误指针,即&error

var error: NSError?
let request = self!.operationManager.requestSerializer.requestWithMethod(method, URLString: url?.absoluteString, parameters: params, error: &error)

我还没有更新我的Xcode。我会尝试使用Xcode 7.1。希望这有所帮助。谢谢! - lazarev
我在更新到Xcode 7.1后,仍然对这段代码存在错误:“传递给不接受参数的调用的参数”。 - lazarev
@lazarev 你是否将它包装在 do {} catch {} 块中?我刚刚再次测试了一下,没有使用 do catch,似乎可以编译通过。你能否发布你正在使用的代码和 AFNetworking 版本? - sbarow
很奇怪。这里的简化版本仍然存在问题: https://gist.github.com/lazarev/127e27f6bc235338fcbd至于版本,那是我的另一个问题。我收到了一个带有许多依赖项混合在没有任何依赖项控制解决方案的代码库的项目。我无法确定确切的版本。但根据某些文件中的版权日期(2015年),它应该至少是2.5.1。 - lazarev
@lazarev,你需要使用错误指针,将error改为&error。你发布的代码示例仍然没有使用指针。 - sbarow
哦是的。 你是对的。 我忘记了这个。 但是在这种情况下,我有这个错误:'&' used with non-inout argument of type '()'。在这篇博客文章中,我发现了相同的情况: http://www.pixeldock.com/blog/how-to-pass-an-error-pointer-to-a-function-in-swift/但错误消息是不同的:'&' used with non-inout argument of type 'NSErrorPointer' (aka 'AutoreleasingUnsafeMutablePointer>')看起来在我的情况下,编译器无法理解此参数的类型。 - lazarev

-1

Swift 2更倾向于仅为必要的方法提供Try Catch块。因此,如果您的方法有可能需要错误处理的情况,那么只需提供此块即可。

do {    
   try managedObjectContext.save() 
} catch {

   // Replace this implementation with code to handle the error appropriately.

   // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

   let NSError = error as NSError

   NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
   abort()
}

实际上,我需要提供更精确的有关此机制的链接。我将其放在底部。我了解如何处理Swift 2中的错误。但是,Swift 2会自动从Objective C更改旧样式选择器。而这个“特性”可能会产生与其他选择器冲突的选择器,就像我在我的示例中展示的那样。我不知道在这种情况下该怎么办。https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html#//apple_ref/doc/uid/TP40014216-CH7-ID10 - lazarev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接