Позволяет разбить исходную строку кода:
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
.
@ Аниш 웃, который не отвечает на вопрос: оба примера, предоставленные OP, являются downcasting.Он спрашивает о различиях между ними, а код в образце Apple использует подход, который он сделал. – johnbakers
Это был не ответ. Просто ссылка, на которую он мог ссылаться для исследования –
Yup - Я думаю, что знаю о downcasting ... :) – SomaMan