web-dev-qa-db-ja.com

キーワード「weak」をクラスおよびクラスバインドプロトコルタイプにのみ適用できる理由

Swiftで変数をweakとして宣言すると、Xcodeからエラーメッセージが表示されることがあります。

「弱い」は、クラスおよびクラスにバインドされたプロトコルタイプにのみ適用できます

キーワードweakがクラスおよびクラスにバインドされたプロトコルタイプにしか適用できないのはなぜだろうと思っていましたか?その背後にある理由は何ですか?

65
Thor

weakは、参照型の修飾子です(structsや組み込みの値型などの値型とは異なります)。

参照タイプを使用すると、同じオブジェクトへの複数の参照を作成できます。最後の強い参照が参照を停止すると、オブジェクトの割り当てが解除されます(弱い参照はカウントされません)。

一方、値タイプはコピーによって割り当てられます。参照カウントは適用されないので、weak修飾子はそれらに対して意味をなしません。

56
dasblinkenlight

このエラーの一般的な理由の1つは、自分がプロトコルを所有していると宣言したが、NSObjectProtocolから継承するのを忘れたことです。

protocol PenguinDelegate: NSObjectProtocol {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate: PenguinDelegate?
}

NSObjectProtocolから継承するのを忘れると、上記のコードはエラーになります。 weakは、参照型(クラス)に対してのみ意味があるためです。したがって、PenguinDelegateは値型ではなくクラスを対象としていることを明確に述べることで、コンパイラーの緊張を軽減します。

123
Jak
protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate: PenguinDelegate?
}

プロトコルの後にクラスを入力すると同様に機能し、NSObjectProtocolの場合よりも適切であると思われます。

60
Aaronium112

私のようにコードのすべてが正しいと誰かが考えている場合に備えて、:=に誤って置き換えていないことを確認してください。

これが私が持っていたものです。また、上記と同じエラーが表示されました。

protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate = PenguinDelegate?
}

しかし、正しい方法は次のとおりです。

protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate: PenguinDelegate?
}

違いがわかりますか?コロンの代わりに等号が表示されているのを見るのに少し時間がかかりました。また、最初のエラーが本当の問題である可能性が高いと判断したため、同じ行で他のエラーが発生したことに注意してください。

-weakは、クラスおよびクラスにバインドされたプロトコルタイプにのみ適用できます

:-<

12
Patrick Miron

weakは、ARC(自動参照カウント)用です。参照カウントを追加しないことを意味します。したがって、Classに対してのみ機能します。また、Swiftでは、セキュリティのオプション値を取得します。

2
Lumialxk

あるケースでは、クラスタイプさえ持っていても、このエラーメッセージが表示される場合があります。

例えば、

class MyVC: UIViewController {
   var myText: UITextView = {
      [weak self]
      let text = UITextView()
      // some codes using self
      return text
   }()
}

ここで、UITextViewオブジェクトは、var myTextの初期化として匿名ブロックから返されます。同じ種類のエラーメッセージが表示されました。この問題を解決するには、varlazyとしてマークする必要があります。

class MyVC: UIViewController {
   lasy var myText: UITextView = {
      [weak self]
      let text = UITextView()
      // some codes using self
      return text
   }()
}
2
David.Chu.ca

参考までに、誰も更新されていません。 Swift提案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 に記載されていますclassの代わりにAnyObjectを使用します。そのため、:classは将来廃止される可能性があります。

1
Dren

クロージャーのString型とArray型のプロパティをキャプチャしようとしました。私はこれらのエラーを受け取りました:

「弱い」は、「[String]」ではなく、クラスおよびクラスにバインドされたプロトコルタイプにのみ適用できます。

「弱い」は、「String」ではなく、クラスおよびクラスにバインドされたプロトコルタイプにのみ適用できます。

私は遊び場でしばらく遊びましたが、結局のところ、これらのタイプには自己をキャプチャするだけで十分です。

1
catanore

enter image description here scrolViewのSwiftでObjective Cクラスを使用していました。そのスクロールビューのIBOutletを作成しました。そして、コードのコンパイル中にこのエラーが表示され始めました。

この種の問題を修正するには、ブリッジングヘッダーにそのクラスをインポートします

import "YourClass.h"

Swift 3.2でXcode 9.2を使用していました

1
Pramod More