如何在 Swift 中正确获取 Do-Catch 范围之外的值(使用 Try)
Posted
技术标签:
【中文标题】如何在 Swift 中正确获取 Do-Catch 范围之外的值(使用 Try)【英文标题】:How Properly to Get the Value Outside of the Scope Do-Catch (using Try) in Swift 【发布时间】:2016-01-19 08:40:32 【问题描述】:我正在尝试将 JSON 数据解析为字典,用于解析我使用的是单独的方法,稍后想将结果(字典)用于另一种方法中的其他操作,而不仅仅是按原样打印出来在网上的许多例子中给出,例如。 G。 here.
但是,我不能返回值,因为我被要求在 guard 中插入 return 语句,但是在插入后得到“非 void 函数应该返回一个值” .
代码如下所示:
func extractJSONDictionaryFrom(JSONData:NSData) ->NSMutableDictionary
var dict = NSMutableDictionary()
do
guard let JSON = try NSJSONSerialization.JSONObjectWithData(JSONData, options:NSJSONReadingOptions(rawValue: 0)) as? NSDictionary else
print("Not a Dictionary")
return
dict = NSMutableDictionary(dictionary: JSON)
catch let JSONError as NSError
print("\(JSONError)")
print("The JSON is \(dict)")
return dict
The approach 使用 throw 也几乎没有用,因为我需要在调用“extractJSONDictionaryFrom”时处理其他方法中的 throws
【问题讨论】:
为什么throw
不好?如果方法被标记为throws
错误,那么如果你在没有do
-catch
块的情况下执行JSONObjectWithData
,则会抛出NSJSONSerialization
错误。但是您可以选择抛出您自己的错误(无论是自定义 ErrorType
类型,如该链接中所示,或者您自己的 NSError
对象,如果您愿意)。
但是当我调用该方法时,我需要在另一个方法中处理抛出,不是吗?我想只处理一种方法,以后避免这样做。
没关系,但是如果你不抛出错误,你必须检查nil
,你不会知道它为什么失败。但是如果调用者不需要知道失败的原因,那么继续使用可选的。使用任何你想要的方法。
【参考方案1】:
一种选择是让您的方法抛出错误(无论是 NSJSONSerialization
错误,因为 JSON 解析完全失败,还是您的自定义错误,如果 JSON 解析有效,但由于某种原因它不是字典):
func extractJSONDictionaryFrom(JSONData: NSData) throws -> NSMutableDictionary
guard let JSON = try NSJSONSerialization.JSONObjectWithData(JSONData, options:[]) as? NSDictionary else
throw NSError(domain: NSBundle.mainBundle().bundleIdentifier!, code: -1, userInfo: [NSLocalizedDescriptionKey : "Not a dictionary"])
return NSMutableDictionary(dictionary: JSON)
或者,另一种方法是不让它抛出错误,而是在转换失败时返回nil
:
func extractJSONDictionaryFrom(JSONData: NSData) -> NSMutableDictionary?
do
guard let JSON = try NSJSONSerialization.JSONObjectWithData(JSONData, options:NSJSONReadingOptions(rawValue: 0)) as? NSDictionary else
print("Not a Dictionary")
return nil
return NSMutableDictionary(dictionary: JSON)
catch let JSONError as NSError
print("\(JSONError)")
return nil
我倾向于前者,但后者也有效。
【讨论】:
那(你的第二种方法)引发了另一个问题:Nil 与返回类型 'NSMutableDictionary' 不兼容 @DariusMiliauskas - 注意,正式的,如果您不想抛出错误,我建议将其更改为NSMutableDictionary?
(可选)。这样您就可以返回nil
。要么使返回类型可选,要么抛出错误。这是让调用者知道 JSON 解析由于某种原因失败的两种合乎逻辑的方式。【参考方案2】:
将结果设为可选 (NSMutableDictionary?
) 并使用 return nil
。
如果调用者不应更改返回的字典,您可能还想返回 NSDictionary?
。
编辑
给出的代码不起作用,因为NSJSONSerialization.JSONObjectWithData
在给定无效 JSON 的情况下会抛出错误,这会被catch
捕获。该函数返回一个空字典而不是nil
。我会尝试以下方法:
func extractJSONDictionaryFrom(JSONData:NSData) ->NSMutableDictionary?
var dict = NSMutableDictionary()
do
guard let JSON = try NSJSONSerialization.JSONObjectWithData(JSONData, options:NSJSONReadingOptions(rawValue: 0)) as? NSDictionary else
print("Not a Dictionary")
return nil
dict = NSMutableDictionary(dictionary: JSON)
catch let JSONError as NSError
print("\(JSONError)")
return nil
print("The JSON is \(dict)")
return dict
我也相信传播异常会更好。
或者,您可以为所有错误返回一个空字典而不使用可选结果,但这“隐藏”错误可能是个坏主意。
【讨论】:
错误:Nil 与返回类型“NSMutableDictionary”不兼容 我不确定在这种情况下“不兼容”是什么意思。以上是关于如何在 Swift 中正确获取 Do-Catch 范围之外的值(使用 Try)的主要内容,如果未能解决你的问题,请参考以下文章
Swift 中的复杂 JSON。如何正确获取数据。不同的结构