Почему ключевое слово "слабый" может применяться только к классам и типам протоколов с привязкой к классам
когда я объявляю переменные как weak в Swift, я иногда получаю сообщение об ошибке от Xcode:
"слабый" может применяться только к классам и типам протоколов с привязкой к классам
мне просто интересно, почему слово weak может применяться только к классам и типам протоколов с привязкой к классам? В чем причина этого?
9 ответов:
weakявляется отборочным для ссылочных типов (в отличие от типов значений, таких какstructs и встроенные типы значений).типы ссылок позволяют иметь несколько ссылок на один и тот же объект. Объект освобождается, когда последняя сильная ссылка перестает ссылаться на него (слабые ссылки не учитываются).
типы значений, с другой стороны, назначаются копию. Подсчет ссылок не применяется, поэтому
weakмодификатор не имеет смысла с ними.
одной из распространенных причин этой ошибки является то, что вы объявили свой собственный протокол, но забыли наследовать от NSObjectProtocol:
protocol PenguinDelegate: NSObjectProtocol { func userDidTapThePenguin() } class MyViewController: UIViewController { weak var delegate: PenguinDelegate? }приведенный выше код даст вам ошибку, если вы забыли, чтобы наследовать от
NSObjectProtocol. Причина в том, чтоweakимеет смысл только для ссылочных типов (классов). Таким образом, Вы делаете компилятор менее нервным, четко заявляя, что PenguinDelegate предназначен для классов, а не для типов значений.
protocol PenguinDelegate: class { func userDidTapThePenguin() } class MyViewController: UIViewController { weak var delegate: PenguinDelegate? }Если вы вводите класс после вашего протокола, он также работает и кажется более подходящим для NSObjectProtocol.
ну на всякий случай, если кто-то еще думает, что у вас есть все правильно в вашем коде, как я, проверьте, что вы не по ошибке заменили
:на=.вот что у меня было. Это также дает мне ту же ошибку, что и выше:
protocol PenguinDelegate: class { func userDidTapThePenguin() } class MyViewController: UIViewController { weak var delegate = PenguinDelegate? }но правильный путь:
protocol PenguinDelegate: class { func userDidTapThePenguin() } class MyViewController: UIViewController { weak var delegate: PenguinDelegate? }вы видите разницу? Мне потребовалось некоторое время, чтобы увидеть, что у меня был знак равенства вместо двоеточия. Также обратите внимание, что я получил другие ошибки для той же строки для I решил, что моя первая ошибка кажется наиболее вероятной реальной проблемой:
-
weakможет применяться только к классам и типам протоколов с привязкой к классам: -
я узнаю в одном случае, когда у вас даже есть тип класса, но все же вы получаете это сообщение об ошибке.
например,
тегиclass MyVC: UIViewController { var myText: UITextView = { [weak self] let text = UITextView() // some codes using self return text }() }UITextView"объект" возвращается из анонимного блока инициализацииvar myText. Я получил тот же тип сообщения об ошибке. Чтобы решить эту проблему,varсталоlazy:class MyVC: UIViewController { lasy var myText: UITextView = { [weak self] let text = UITextView() // some codes using self return text }() }
weakдля дуги (автоматический подсчет ссылок). Это означает, что вы не добавляете счетчик ссылок. Так что это работает только дляClass. И в Swift, вы получите дополнительное значение для безопасности.
Я попытался захватить строковые и массивные свойства для закрытия. Я получил эти ошибки:
'слабый' может быть применен только к классу и связанным с классом типам протоколов, а не'[String]'
'слабый' может быть применен только к классу и связанным с классом типам протоколов, а не'String'
Я играл некоторое время на детской площадке, и оказалось, что захвата себя достаточно для этих типов.
просто FYI и кто не обновляется. После быстрого предложения SE-0156 https://github.com/apple/swift-evolution/blob/master/proposals/0156-subclass-existentials.md был реализован, есть в Swift docs "Class-Only Protocols section"https://docs.swift.org/swift-book/LanguageGuide/Protocols.html теперь описано использовать какой-либо объект, а не класс. Так что, это возможно для класс будет прекращена в будущем.

Comments