Swift 循环反向运行?代码难题

Swift loop runs in reverse? Code conundrum

提问人:user3069232 提问时间:3/20/2023 最后编辑:user3069232 更新时间:3/20/2023 访问量:31

问:

我不明白这段代码中发生了什么......

fileprivate func genericNodeWalker(_ direction:Follow, encapsulatedMethod: @escaping (_ iNode:Int) -> Void) {
    switch direction {
    case .forwards:
        for nodeIndex in 0..<self.nodes.count {
            encapsulatedMethod(nodeIndex)
        }
    case .backwards:
        for indexNode in stride(from: self.nodes.count - 1, through: 0, by: -1) {
       // for nodeIndex in (0..<self.nodes.count).reversed() {
            print("indexNode \(indexNode)")
            encapsulatedMethod(indexNode)
        }
    }
}

fileprivate func fadeOutNodes2() {
    genericNodeWalker(.backwards) { index2D in
        let wait = SKAction.wait(forDuration: Double(index2D) * 2)
        let custom = SKAction.run {
            print("index2D \(index2D)")
        }
        let sequence = SKAction.sequence([wait,custom])
        self.nodes[index2D].run(sequence)
    }
}

我要求它倒数,它确实如此;但是 encapsulatedMethod 中的代码 fadeOutNodes2 向前运行?

indexNode 6
indexNode 5
indexNode 4
indexNode 3
indexNode 2
indexNode 1
indexNode 0
index2D 0
index2D 1
index2D 2
index2D 3
index2D 4
index2D 5
index2D 6

这里有一个明显的错误,我不能,我不能只见树木不见木头?如果我将循环更改为向前运行,它也会向前运行。

我怎样才能让它向后运行?

Swift Loops 闭合 Skaction

评论

3赞 Geoff Hackworth 3/20/2023
genericNodeWalker 的回调是反向调用的,但在执行自定义操作之前,您插入了 2 * index2D 的延迟。这意味着第一个调用(index2D = 6)将延迟 12 秒,下一个调用(index2D = 5)将延迟 10 秒。等等。这意味着动作内的打印将看起来是相反的。
1赞 Joakim Danielson 3/20/2023
您应该为您的问题添加适当的标签,因为问题似乎与此类型有关。SKAction
0赞 user3069232 3/20/2023
当你说出来时,这听起来很明显;谢谢!!我敢说一个很好的考试问题......
0赞 Joakim Danielson 3/20/2023
如果此问题已解决,请删除该问题。
0赞 user3069232 3/20/2023
@joakim-丹尼尔森:我发布了答案让其他人受益?你认为我应该删除它吗?

答:

1赞 Geoff Hackworth 3/20/2023 #1

我不太确定你想做什么,但对你来说更好的 API 可能是这样的(我假设是一个数组,如果需要,请更改类型):genericNodeWalkernodesSKNode

fileprivate func genericNodeWalker(_ direction:Follow, encapsulatedMethod: (_ index: Int, _ node: SKNode) -> Void) {
    switch direction {
    case .forwards:
        nodes.enumerated().forEach(encapsulatedMethod)
    case .backwards:
        nodes.reversed().enumerated().forEach(encapsulatedMethod)
    }
}


fileprivate func fadeOutNodes2() {
    genericNodeWalker(.backwards) { index, node  in
        let wait = SKAction.wait(forDuration: Double(index) * 2)
        let custom = SKAction.run {
            print("index \(index)")
        }
        let sequence = SKAction.sequence([wait,custom])
        node.run(sequence)
    }
}

walker 只会按照您要求的顺序调用节点的回调,并且每次调用时都会传递一个从零开始的递增索引。

因此,如果你有节点通过,那么 walker 将在向前交互时调用 , ,并在向后迭代时调用 , , 。步行者不在乎你用索引做什么。它不在乎延迟。它只是按照您要求的顺序将节点传送到回调方法,并为每个从 0 开始的节点提供索引。acencapsulatedMethod(0,a)(1,b)(2,c)(0,c)(1,b)(2,a)

这也意味着回调函数本身被传递了 a,不需要根据索引找到它。也没有必要使用,因为回调闭包不会转义。在返回之前,将对每个节点调用它。nodeself.nodes@escapinggenericNodeWalker

也许这样更好,也许不是。但我认为它是一个更干净的 API。