web-dev-qa-db-ja.com

「宣言されていないセレクタ」警告を取り除く方法

NSObjectインスタンスでセレクターを使用したいwithout実装されたプロトコルの必要性。たとえば、呼び出されたNSObjectインスタンスがサポートしている場合にエラープロパティを設定するカテゴリメソッドがあります。これがコードであり、コードは意図したとおりに機能します。

if ([self respondsToSelector:@selector(setError:)])
{
    [self performSelector:@selector(setError:) withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]];
}

ただし、コンパイラはsetError:シグネチャを使用したメソッドを認識しないため、@selector(setError:)スニペットを含む各行に対して警告が表示されます。

Undeclared selector 'setError:'

この警告を取り除くためにプロトコルを宣言する必要はありません。これを使用するすべてのクラスが特別なものを実装することは望まないからです。慣例により、それらにsetError:メソッドまたはプロパティを持たせたい。

これは実行可能ですか?どうやって?

乾杯、
EP

160
epologee

別のオプションは、次を使用して警告を無効にすることです。

#pragma GCC diagnostic ignored "-Wundeclared-selector"

この行は、警告が発生する.mファイルに配置できます。

更新:

次のようなLLVMでも機能します。

#pragma clang diagnostic Push
#pragma clang diagnostic ignored "-Wundeclared-selector"

... your code here ...

#pragma clang diagnostic pop
247
Klaas

NSSelectorFromString をご覧ください。

 SEL selector = NSSelectorFromString(@"setError:");
 if ([self respondsToSelector:selector])

これにより、コンパイル時に@selectorキーワードを使用する代わりに、実行時にセレクターを作成でき、コンパイラーは文句を言う機会がなくなります。

191
sergio

これは、何らかの奇妙な理由でセレクタがランタイムに登録されていないためだと思います。

sel_registerName() でセレクターを登録してみてください:

SEL setErrorSelector = sel_registerName("setError:");

if([self respondsToSelector:setErrorSelector]) {
   [self performSelector:setErrorSelector withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]];
}
52
Jacob Relkin

私はこのスレッドに少し遅れていることを理解していますが、完全を期すために、ターゲットのビルド設定を使用してこの警告をグローバルにオフにすることができます。

「Apple LLVM警告-Objective-C」セクションで、次を変更します。

Undeclared Selector - NO
7
Quixiote

メソッドでファイルを#includeすることで、このメッセージを消しました。そのファイルからは何も使用されていません。

7
Mark Patterson

クラスがsetError:メソッドを実装する場合(最終的なエラープロパティのセッターを動的に宣言することによっても)、インターフェイスファイル(.h)で宣言するか、そのように表示したくない場合PrivateMethodsのトリッキーなトリックを試してください。

@interface Yourclass (PrivateMethods)

- (void) yourMethod1;
- (void) yourMethod2;

@end

@implementationの直前に、警告を非表示にする必要があります;)。

5
i_mush

.pchまたはCommon.hまたは任意の場所に配置できる非常に快適なマクロ:

#define SUPPRESS_UNDECLARED_SELECTOR_LEAK_WARNING(code)                        \
_Pragma("clang diagnostic Push")                                        \
_Pragma("clang diagnostic ignored \"-Wundeclared-selector"\"")     \
code;                                                                   \
_Pragma("clang diagnostic pop")                                         \

それは この質問 の編集です。同様の問題については...

3
Aviel Gross

この警告を回避する別の方法は、セレクターメソッドが次のようになることを確認することです。

-(void) myMethod :(id) sender{
}

送信者を受け入れるか、必要に応じて送信者オブジェクトのタイプを指定する場合は、「(id)sender」を忘れないでください。

2
Repose

スクリーンショットのようにXcodeでオフにできます:

enter image description here

2
SmallChess

問題のオブジェクトを最初にidにキャストして、警告を回避することもできます。

if ([object respondsToSelector:@selector(myMethod)]) {
    [(id)object myMethod];
}
1
Swindler

正しい答えは、インポートを介してXcodeに通知するか、セレクターにそのようなセレクターが存在することを登録することにありますが、私の場合はセミコロンがありませんでした。エラーを「修正」する前に、おそらくエラーが正しく、コードが正しくないことを確認してください。たとえば、AppleのMVCNetworkingサンプルでエラーを見つけました。

0
Louis St-Amour