func fetchOrders(_ completionHandler: (_ orders: [Order]) -> Void) { ordeRSStore.fetchOrders { (orders: () throws -> [Order]) -> Void in do { let orders = try orders() completionHandler(orders) } catch { completionHandler([]) } } }
> fetchOrders中的_ completionHandler参数是什么意思?
>什么(订单:()抛出 – > [订单])是什么意思?
PS:我是iOS和Swift的新手
func fetchOrders(_ completionHandler: (_ orders: [Order]) -> Void)
>这是一个名为fetchOrders的函数.
>它有一个参数(completionHandler)并且不返回任何内容.
>第一个_表示第一个参数没有“外部名称”.也就是说,你不必标记它(事实上,你不能). (由于微妙的原因在这里并不重要,我相信作者在那里使用_时犯了一个错误,我不会这样做.)
> completionHandler是“内部名称”,在函数内部调用参数.
> completionHandler的类型是(_ orders:[Order]) – >虚空.我们现在打破这个.
>该值是一个闭包,它接受[Order](Order数组)并返回Void.非正式地,这意味着“什么都不返回”,但字面意思是它返回空元组().
> _ orders:语法实际上是一个注释.原则上_是一个外部名称(但这是闭包的唯一合法外部名称),而orders是一个内部名称,但实际上,闭包参数没有任何有意义的名称,所以这纯粹是信息性的.
>我认为这是封闭参数注释系统的一个很好的用法.由于订单只告诉我们[订单],我会省略它,并使类型只是([订单]) – >虚空.
现在我们将转向下一行:
ordeRSStore.fetchOrders { (orders: () throws -> [Order]) -> Void in
>这会调用ordeRSStore上的fetchOrders方法.我们可以从这段代码中看出fetchOrders采用了一个闭包参数.这在Swift中称为“尾随闭包”语法,这就是为什么我不会将_用于闭包.使用尾随闭包语法,不需要参数的外部名称.
>作者在这里提供了可能没有必要的类型信息,但无论如何我们都可以探索它.这可能只是写入{订单,但读者可能会对这个有点不寻常的代码感到惊讶.
>我们已经传递了一个名为orders的闭包,它不接受任何操作并返回[Order]或抛出错误.基本上这是一种说fetchOrders可能会失败的方法.
>作者正在解决Swift的throws系统中的尴尬,它没有一种自然的方式来表达可能失败的异步操作.这是解决它的一种方法;你通过投掷(即可能失败)的功能.我不喜欢这种方法,我赞成在这种情况下使用Result枚举,因为我认为它可以更好地扩展并避免可能的意外副作用,但这是一个值得商榷的问题(并且Swift社区还没有真正决定如何处理这个问题常见问题).
这一切都引导我们:
do { let orders = try orders() completionHandler(orders) } catch { completionHandler([]) }
>这是评估订单关闭的地方. (这非常重要;如果订单有副作用,这就是它们发生的时间,它可能与预期的队列不同.这是我不喜欢这种模式的一个原因.)如果闭包成功,我们返回结果,否则我们在下面的回合中返回[].
>在这种特殊情况下,抛出方法略显愚蠢,因为它甚至在没有日志消息的情况下无声地扁平化为[].如果我们不关心错误,那么失败应该刚刚返回[]开始而不是抛出抛出.但是其他呼叫者可能会检查错误.
>在任何一种情况下,我们都会使用我们的结果调用completionHandler闭包,将其链接回原始调用者.
这个do / catch块可以更简单地写成:
let completedOrders = try? orders() ?? [] completionHandler(completedOrders)