Развертывание опций в шаблоне проекта игрового кода Apple
В небольшом примере кода Apple, который создается при создании нового игрового проекта в Xcode, GameScene имеет несколько функций, которые используют шаблон развертывания, с которым я не сталкивался, и я не вижу смысла в этом -
if let n = self.spinnyNode?.copy() as! SKShapeNode? { ...code... }
Два вопроса - (1) это опасно, и (2) почему бы не использовать более общий шаблон -
if let n = self.spinnyNode?.copy() as? SKShapeNode { ...code... }
Я не могу найти ничего относящегося к этому на SO или Google...
1 ответ
Давайте разберем исходную строку кода:
if let n = self.spinnyNode?.copy() as! SKShapeNode? { ...code... }
self.spinnyNode
объявлен какSKShapeNode?
, Другими словами, это необязательноSKShapeNode
,SKShapeNode
наследуется отNSObject
который обеспечиваетcopy
метод.copy
метод объявлен для возвратаAny
,self.spinnyNode?.copy()
вернетAny?
со значениемnil
еслиself.spinnyNode
являетсяnil
или он вернет не нольAny?
если это не так.
Таким образом, компилятор считает, что self.spinnyNode?.copy()
вернет Any?
, Но мы знаем, что это действительно вернет SKShapeNode?
, Так как мы знаем, что это будет на самом деле, мы можем безопасно использовать as!
, И так как мы знаем, он вернет SKShapeNode?
, мы используем as! SKShapeNode?
,
На данный момент мы могли бы иметь:
let n = self.spinnyNode?.copy() as! SKShapeNode?
где n
будет SKShapeNode?
,
Поскольку теперь мы хотим безопасно развернуть результат, добавим if
напротив let
:
if let n = self.spinnyNode?.copy() as! SKShapeNode? { ...code... }
и внутри блока мы знаем, что n
не ноль SKShapeNode
,
Со всем этим давайте ответим на ваши вопросы:
- Это опасно? Нет, не в этом случае, так как мы точно знаем, что
self.spinnyNode?.copy()
всегда приведет кSKShapeNode?
мы можем безопасно использоватьas!
бросить егоSKShapeNode?
, - Почему бы не использовать более распространенный
as? SKShapeNode
шаблон? Мы могли бы, но этот шаблон используется, когда вы не знаете наверняка, что результат на самом делеSKShapeNode
,