ここのガイドに従って、カスタム デリゲートを作成します。正常に動作しますが、xcode で次の警告が表示されます
DetailViewController.m:23:1: 自動合成されたプロパティ 'delegate' は、既存のインスタンス変数 'delegate' ではなく、合成されたインスタンス変数 '_delegate' を使用します
誰でも警告を取り除く方法をアドバイスできますか
ここのガイドに従って、カスタム デリゲートを作成します。正常に動作しますが、xcode で次の警告が表示されます
DetailViewController.m:23:1: 自動合成されたプロパティ 'delegate' は、既存のインスタンス変数 'delegate' ではなく、合成されたインスタンス変数 '_delegate' を使用します
誰でも警告を取り除く方法をアドバイスできますか
この状況を処理する最も慣用的な方法は、単純にdelegate
ivar 宣言を削除することです。ivar を使用していた場合は、代わりdelegate
に暗黙の ivar を使用する必要があります_delegate
。
なぜこれが機能するのですか?
Xcode 4.4 (LLVM Compiler 4.0)の時点で、ディレクティブがそのプロパティに対して明示的に使用されていない場合@synthesize
、インスタンス変数とアクセサ メソッドはそのプロパティに対して自動的に合成されます。カプセル化状態に関するAppleのドキュメントとして
デフォルトでは、[...] アクセサー メソッドはコンパイラによって自動的に合成されるため、クラス インターフェイスで @property を使用してプロパティを宣言する以外に何もする必要はありません。
プロパティ (自動的に合成されたプロパティ アクセサー メソッドによって取得および設定される) に使用される ivar には名前が付けられます_<propertyName>
(つまり、ivar の名前は、プロパティの名前の前にアンダースコアが付きます)。
この場合、プロパティ名はdelegate
であるため、使用される ivar は です_delegate
。これはあなたのコードですでに起こっています。andを呼び出す-delegate
と-setDelegate:
、この ivar_delegate
が取得および設定されます。
ただし、独自の ivar も宣言していますdelegate
。もちろん、明示的に宣言した ivar ( delegate
) は、インスタンス メソッドによって取得および設定されません。-delegate
これ-setDelegate:
は、自動的に合成された ivar ( _delegate
) が取得および設定されているためです。ただし、(ほとんどの場合、そうでない場合、コードはあいまいです) あなたの意図は、ivardelegate
がプロパティのアクセサーが取得および設定するものになることでした。幸いなことに、コンパイラはあなたが行ったことに気付くほど賢いので、次の警告が表示されます。
警告: 自動合成されたプロパティ ' ' は、既存のインスタンス変数 ' ' ではなく、
delegate
合成されたインスタンス変数 ' ' を使用します[ ]_delegate
delegate
-Wobjc-autosynthesis-property-ivar-name-match
プロパティが、明示的に宣言した ivar ではなくdelegate
、自動的に合成された ivar を使用することを示しています。_delegate
delegate
したがって、単純にdelegate
ivar を削除すると、コンパイラはこの警告の発行を停止します。delegate
ivar を (プロパティ経由ではなく) 直接使用していた場合は、_delegate
代わりに使用を開始してください。
このオプションのマイナー バリエーションは、プロパティ_delegate
の自動合成が作成するのと同じ ivar ( )を明示的に宣言することです。delegate
置き換えることでこれを行うことができます
@interface TheClass : TheSuperclass
{
//...
id<TheDelegateProtocol> delegate
//...
}
@end
と
@interface TheClass : TheSuperclass
{
//...
id<TheDelegateProtocol> _delegate
//...
}
@end
これが機能するのは、プロパティの自動合成では常に、プロパティの名前の前にアンダースコアが付けられた ivar が使用されるためです。そのような ivar が存在しない場合は、ivar が生成されます。存在する場合は、それが使用されます。
代わりに、プロパティのアクセサーを設定して ivar を取得したい場合は、クラスにディレクティブをdelegate
追加して、コンパイラにこれを行うように指示できます。@synthesize
@implementation
@implementation TheClass
//...
@synthesize delegate = delegate;
//...
@end
この行は、プロパティ(割り当ての左側) のアクセサーで@synthesize delegate = delegate;
ivar delegate
(割り当ての右側)を使用するようコンパイラーに指示します。delegate
@synthesize
割り当ての右側を省略して、単に書くこともできます
@implementation TheClass
//...
@synthesize delegate;
//...
@end
これが機能@synthesize
するのは、アクセサー ( など) によって取得および設定される ivar を明示的に指定していないマニュアルを@synthesize delegate;
持つプロパティは、アンダースコアをプレフィックスとして付けずに、プロパティと同じ名前の ivar を使用するためです。これは下位互換性に関係しています。
別の方法があり、これは私のために働いた:
@property (nonatomic, unsafe_unretained) id <MyDelegate> delegate;
その後、これをエラーなしで実装に追加できます。
@synthesize delegate;
また、これは ARC 準拠です。