590

weakprotocolaが として宣言されていない限り、参照は Swift で機能しないようです@objc。これは、純粋な Swift アプリでは望ましくありません。

このコードはコンパイル エラーを返します (weak非クラス型には適用できませんMyClassDelegate)。

class MyClass {
  weak var delegate: MyClassDelegate?
}

protocol MyClassDelegate {
}

プロトコルの前に を付ける必要があり@objc、それが機能します。

質問: を達成するための「純粋な」Swift の方法は何weak delegateですか?

4

7 に答える 7

1108

プロトコルのタイプを として宣言する必要がありますAnyObject

protocol ProtocolNameDelegate: AnyObject {
    // Protocol stuff goes here
}

class SomeClass {
    weak var delegate: ProtocolNameDelegate?
}

Youを使用AnyObjectすると、このプロトコルに準拠できるのはクラスのみであり、構造体または列挙型は準拠できないと言えます。

于 2014-06-08T08:35:30.417 に答える
40

AnyObjectSwift で弱参照を使用する公式の方法です。

class MyClass {
    weak var delegate: MyClassDelegate?
}

protocol MyClassDelegate: AnyObject {
}

アップル より:

強い参照の循環を防ぐには、デリゲートを弱い参照として宣言する必要があります。弱参照の詳細については、「クラス インスタンス間の強参照サイクル」を参照してください。プロトコルをクラスのみとしてマークすると、デリゲートが弱い参照を使用する必要があることを後で宣言できます。クラスのみのプロトコルで説明されているように、 AnyObjectから継承することにより、プロトコルをクラスのみとしてマークします。

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID276

于 2018-02-19T14:18:05.453 に答える
8

更新: マニュアルが更新され、参照していた例が削除されたようです。上記の@flainezの回答の編集を参照してください。

オリジナル: Obj-C と相互運用していなくても、@objc を使用するのが正しい方法です。プロトコルが列挙型や構造体ではなく、クラスに適用されていることを確認します。マニュアルの「プロトコル適合性の確認」を参照してください。

于 2014-06-07T06:26:45.970 に答える
1

弱い修飾子は、参照オブジェクトにのみ適用されます。@objcプロトコルに、AnyObject、または修飾子を追加しない限りclass、プロトコルに準拠するオブジェクトは参照オブジェクトではない可能性があります。

したがって、これらの修飾子が必要です (非AnyObject推奨classになると予想されるため、推奨されます)。

ところで、@objc「純粋な Swift」アプリケーションであっても、クラスとプロパティへの追加が必要になる場合があることに注意してください。開発言語とは関係ありません。これにより、コンパイラは、一部の OS インターフェイス (たとえば、ターゲット/アクションおよび古いスタイルのキー パス) に必要な Objective-C ランタイムと互換性のある方法でコードをビルドします。

于 2021-06-17T11:57:16.290 に答える
-9

Apple は、「クラス」の代わりに「NSObjectProtocol」を使用します。

public protocol UIScrollViewDelegate : NSObjectProtocol {
   ...
}

これも機能し、独自のデリゲート パターンを実装しようとしたときに表示されていたエラーを取り除きました。

于 2016-04-19T16:49:43.627 に答える