我对Swift还是比较陌生,还没有掌握可选控件的安全性方面。

我有一个[String: [SCNNode]]类型的字典。给定的分子在[SCNNode]中将具有多个成分作为元素。对于该分子,我检索了这个组成的数组,并将每个元素分配给本地的SCNNode以进行显示,操作和设置动画。

    let components = moleculeDictionary["aceticAcid"]     // the array of components
        // [baseMolecule, hydrogenCharge, oxygenCharge, ionizingH, ionizedBond, bonds]

    atomsNode_1 = components![0]            // baseMolecule
    baseNode.addChildNode(atomsNode_1)

    atomsNode_5 = components![3]            // ionizingH
    atomsNode_1.addChildNode(atomsNode_5)

   // etc.


为了有选择地绑定它,编译器对此感到满意。

    if let node = components?[0]  {          // baseMolecule
        baseNode.addChildNode(node)
    }


我不清楚?。我对此的阅读表明,我们正在以某种方式展开包装,这样我们就不会在乎是否有零。但这是否使此可选绑定比上面的强制展开更好?还是这个“可选链接”?我应该在分配components时只是检查一下吗?我什至应该对此感到安全吗?我所做的唯一“ upsteam”测试是在将字典存档分配给moleculeDictionary之前是否存在字典存档。

我将有数百个这样的任务,所以我想做对了。欢迎提出最佳处理方法的建议!

谢谢,伯恩

最佳答案

我认为,您应该担心Swift的安全性。给定上面的代码,我将在第一遍中将其重写为:

guard let components = moleculeDictionary["aceticAcid"] where components.count > 3 else { // handle the case where there is no value for this key, or not enough nodes }

// Now I know that I have the correct number of components I don't need to  force unwrap:

atomsNode_1 = components[0]            // baseMolecule
baseNode.addChildNode(atomsNode_1)

atomsNode_5 = components[3]            // ionizingH
atomsNode_1.addChildNode(atomsNode_5)


那是第一次通过。第二遍是确保我对所有组件都具有值,这将是编写一个包含SCNNode值的结构,以便每个节点我都具有一个值或为nil,然后可以构建您的节点结构相应。

编辑添加

这表明第二遍-确实需要比我更多的领域知识,但这是一个开始。

看来您是从[[SCNNode]](由SCNNode组成的数组组成的数组)构建分子的,每个子数组的位置都很重要。值得将其放入自己的结构中,例如:

struct Molecule {
    let baseMolecule: [SCNNode]?
    let hydrogenCharge: [SCNNode]?
    let oxygenCharge: [SCNNode]?
    let ionizingH: [SCNNode]?
    let ionizedBond: [SCNNode]?
    let bonds: [SCNNode]?

    // Other methods can be written to build up atom nodes from within the struct which handle the cases where the component array is nil
}

10-08 08:07