Необязательный эталон по сравнению со слабым в Swift 5.0

Это разрешено в Swift 5.0:

class Person { 
    unowned var child: Person?
}

Это поддерживается примечаниями к выпуску:

переменные unowned и unowned(unsafe) теперь поддерживают необязательные типы. (47326769)

Я точно понял разницу между слабым и неизвестным в Swift 4.2 и до. Однако я не уверен, почему Apple решила сделать unowned optional тип. Даже в документах (которые являются документами для Swift 5.0) это реализованное "предложение" (где я могу даже найти это предложение с мотивацией для добавления необязательных ссылок без ссылок?) Не обновляется, потому что оно говорит:

Ожидается, что неизвестная ссылка всегда будет иметь значение. В результате ARC никогда не устанавливает значение для неподтвержденной ссылки равным nil, что означает, что неподтвержденные ссылки определяются с использованием необязательных типов.

Выше не правда больше. Единственное функциональное отличие, которое заявляет Apple, заключается в том, что unowned ожидается, что ссылка будет иметь равное или большее время жизни, чем объект, содержащий эту ссылку. Ну, мне любопытно техническое использование этого.

Какая разница, когда я использую weak ссылка против необязательного unowned ссылка? Или единственное отличие, которое необязательно unowned следует использовать, когда ссылочный объект имеет более длительный срок службы? Я ожидаю, что должно быть больше...

1 ответ

Решение

Вы неправильно поняли примечание к выпуску и значение изменения языка.

почему Apple решила сделать unowned необязательным типом

Они не Вы можете, и обычно будете, еще сказать

unowned let owner : MyViewController

Единственным изменением здесь является то, что неизвестная переменная может быть необязательной, что ранее было недопустимым. Это изменение заботится о досадном крайнем случае, вот и все.

Выше не правда больше

Да, это. Вещи совершенно не изменились:

  • Слабые ссылки должны быть напечатаны как Необязательные; они не сохраняют указанный объект, но отслеживают указанный объект и возвращаются к nil если этот объект исчезает.
  • Неизвестные ссылки не сохраняют упомянутый объект и не отслеживают упомянутый объект, поэтому вы должны предотвратить исчезновение этого объекта, иначе вы можете получить висящий указатель и сбой.

Единственное, что изменилось, это то, что раньше существовало дополнительное правило, согласно которому неизвестный ссылочный тип не мог быть необязательным. Это правило исчезло.

Как вы правильно заметили, если неизвестный тип ссылки является Необязательным, это должно быть var ссылка, а не let ссылка (потому что наличие этого параметра необязательно, если бы у вас не было возможности изменить его с nil к фактическому значению и наоборот).

Типичный вариант использования очень похож на то, что вы сами предоставили:

class Node {
    unowned var parent: Node?
}

Представляется разумным сказать, что этот узел может иметь или не иметь родителя (потому что он может быть в верхней части графа), но если у него есть родитель, этот родитель должен быть неизвестным (родитель должен сохранить своего потомка, но ребенок не должен сохранять своего родителя). Раньше единственный способ сказать это состоял в том, чтобы сделать это слабой ссылкой, что влечет за собой некоторые ненужные издержки и является бесполезным, потому что мы можем абсолютно гарантировать, что если у узла есть родительский элемент, родительский объект переживет дочерний элемент. Теперь вы можете сказать, что вы имеете в виду, что, как правило, хорошо.

Другие вопросы по тегам