Почему ключевое слово "слабый" может применяться только к классам и типам протоколов с привязкой к классам



когда я объявляю переменные как weak в Swift, я иногда получаю сообщение об ошибке от Xcode:




"слабый" может применяться только к классам и типам протоколов с привязкой к классам




мне просто интересно, почему слово weak может применяться только к классам и типам протоколов с привязкой к классам? В чем причина этого?

631   9  

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'

Я играл некоторое время на детской площадке, и оказалось, что захвата себя достаточно для этих типов.

enter image description hereя использовал класс objective C в swift для scrolView. Я создал IBOutlet этого вида прокрутки. И во время компиляции кода эта ошибка начала отображаться.

поэтому, чтобы исправить эту проблему, импортируйте этот класс в свой заголовок моста

импорт " YourClass.h"

Я использовал Xcode 9.2 с swift 3.2

просто 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

    Ничего не найдено.