Swift 2 中的显式老式错误处理

Posted

技术标签:

【中文标题】Swift 2 中的显式老式错误处理【英文标题】:Explicit old fashioned error handling in Swift 2 【发布时间】:2015-10-27 20:07:13 【问题描述】:

Apple 在 Swift 2 中引入了新奇的错误处理

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

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

- (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 已被弃用,但 second 由 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 中解决这个问题的最佳实践是什么?在这种情况下有没有办法指定特定的选择器?

UPD:关于 Swift 2 功能的更精确链接成为我的问题的一个原因。 https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html#//apple_ref/doc/uid/TP40014216-CH7-ID10

【问题讨论】:

好吧,我知道我会做什么;我会在 Objective-C 中编写一个蹦床方法。 (我会向 AFNetworking 人员提交错误报告。) 是的,如果 Swift 2 没有工具来解决这个问题,它看起来是一个更好的选择。但我不知道 Swift 架构师预测过这样的问题,并且他们有一些适当的方法来克服这类问题。 您确定调用了已弃用的变体吗?也许 Xcode 只是混淆了弃用警告? 【参考方案1】:

似乎这在 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 试试。希望这可以帮助。谢谢! 更新到 Xcode 7.1 后,此代码仍有错误:“参数传递给不带参数的调用” @lazarev 你是否将它包装在do catch 块中?刚刚在没有do catch 的情况下再次测试,它似乎编译得很好。你会发布你正在使用的代码和AFNetworking的版本@ 真奇怪。这里的简化版仍然有问题:gist.github.com/lazarev/127e27f6bc235338fcbd 至于版本,那是我的另一个问题。我收到了包含大量依赖项与代码库混合的项目,没有任何依赖项控制解决方案。我只是无法确定确切的版本。但根据某些文件的版权日期(2015 年),它应该至少是 2.5.1。 @lazarev 您需要使用错误指针将error 更改为&error 您发布的代码示例仍然没有使用指针。【参考方案2】:

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 的旧样式选择器。并且这个“功能”可能会产生与其他选择器冲突的选择器,正如我在示例中所示。我只是不知道在这种情况下该怎么办。 developer.apple.com/library/prerelease/ios/documentation/Swift/…

以上是关于Swift 2 中的显式老式错误处理的主要内容,如果未能解决你的问题,请参考以下文章

Whitelabel 错误页面 - 应用程序没有 /error 的显式映射

实体框架抛出无法在表中插入标识列的显式值...当 IDENTITY_INSERT 设置为 OFF 错误

无法添加表行,因为“当 IDENTITY_INSERT 设置为 OFF 时,无法在表 'Users' 中插入标识列的显式值”错误

处理 Swift 2.0 中的转换错误

ASP.NET MVC 错误 SqlException:当 IDENTITY_INSERT 设置为 OFF 时,无法在表“用户”中插入标识列的显式值

TCP/IP网络中的显式拥塞通告(ECN)