使用可选的完成处理程序调用自身进行迭代,不会第二次完成

Posted

技术标签:

【中文标题】使用可选的完成处理程序调用自身进行迭代,不会第二次完成【英文标题】:iterating using optional completion handler calling itself, wont complete second time around 【发布时间】:2019-02-15 12:41:22 【问题描述】:

我收到此错误:

可选类型 '((RestTime) -> ())?' 的值必须解包为 '(RestTime) -> ()' 类型的值

我从 VC 调用函数:

        let calculateSegmentDirections = CalculateSegmentDirections(locationManager: locationManager)
        calculateSegmentDirections.calculateSegmentDirections(index, time: time, routes: routes, loc: loc)  restTime in
                print("4")

        




    func calculateSegmentDirections(_ index: Int, time: TimeInterval, routes: [MKRoute], loc: LocationModel, completion: ((_ restTime: RestTime) -> ())?) 
            print("1")
            if let routeResponse = response?.routes 
            print("2")
                    self.calculateSegmentDirections(index+1, time: timeVar, routes: routesVar, loc: restLocation, completion: nil)
                 else 
                    let restTime = RestTime(objectID: restLocation.objectID, time: timeVar, routes: routesVar)
                    print("3")
                    completion(restTime)
                
    

完整形式的函数从 VC 调用,然后迭代自身以从 MKdirections 创建路由。我的问题是,我可以以这种方式使用可选的完成处理程序吗?

控制台按预期打印 1、2、1、3,但随后不调用完成。 4永远不会被解雇。 completion = nil,所以当我用 if completion = completion 展开时它不起作用。

另外,completion?(restTime) 也不起作用,将默认值设置为 nil 也不起作用,就像我使用 print(completion) = nil 检查时一样。

猜测发生了什么: 第一个完成处理程序是否“完成功能”因此第二个不触发?我传递了一个 nil 值,而不是不运行它?

抱歉,如果这很简单,谷歌是紫色的,仍然不确定我做错了什么。

【问题讨论】:

“完成?(restTime)也不起作用”。 “不起作用”是什么意思? 【参考方案1】:

我认为问题出在这里:

// ... 
print("2")
self.calculateSegmentDirections(index+1, time: timeVar, 
         routes: routesVar, loc: restLocation, completion: nil)
// ...

当您递归调用calculateSegmentDirections 时,您不会提交完成处理程序,而是提交nil。这是故意的吗?在我看来,这应该是:

// ... 
print("2")
self.calculateSegmentDirections(index+1, time: timeVar, 
         routes: routesVar, loc: restLocation, completion: completion)
// ...

【讨论】:

成功了!虽然我不完全确定为什么。为什么 nil 不起作用,我假设如果我传递 nil,我传递一个 nil 值,而不是不使用完成,因此如果我再次传递完成,它只是“重置”它?非常感谢,这花了我很多时间。 传递nil 不起作用,因为您正在递归地调用函数。第一次调用 (A) 将打印“1”,进入 if 分支,打印“2”,然后再次调用自身 (B),例如calculateSegmentDirections。这将打印“1”,进入else 分支,打印“3”,然后调用完成处理程序(如果不是nil) - 但这是它从 (B) 获得的完成处理程序参数,而不是从 ( A)。 是的,这就是我的想法,我只是不知道我可以将完成传递给它自己的处理程序。非常感谢你说得很清楚,为我节省了很多时间。我现在必须写很多这些,所以会很有用。

以上是关于使用可选的完成处理程序调用自身进行迭代,不会第二次完成的主要内容,如果未能解决你的问题,请参考以下文章

短学期第二次心得

写不了,不会,告辞。程序员三连(第二次站立议会)

如何在 Swift 中创建一个我可以选择调用的完成处理程序?

可选输出光标作为参数

在bash中使用getopts来获取可选的输入参数[重复]

允许 automake 生成可选的编译规则