我对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
}