15

次のようなライブラリにコードを配布しています。

if ([[NSString class] instancesRespondToSelector: @selector(JSONValue)]) {
  NSString *jsonString = [[[NSString alloc] initWithData: jsonData encoding: NSUTF8StringEncoding] autorelease];
  dict = [jsonString performSelector: @selector(JSONValue)];
}

メソッドが呼び出されると、何らかの理由で-[__NSCFString JSONValue]: unrecognized selector sent to instance例外がスローされます。performSelector:これは私が書いたライブラリで配布されているコードですが、自分で再現またはデバッグすることはできません。代わりに、サードパーティがこの問題を報告しています。instancesRespondToSelector:実際にperformSelector:例外をスローしてメソッドを呼び出しているときに、どのような条件下で発生する可能性がありますか?

編集 なぜこれが起こるのか説明できるケースがありますが、意味がありません. 開発者が次のようなことをした場合:

@implementation NSString (OurHappyCategory)

+ (BOOL)instancesRespondToSelector:(SEL)aSelector
{
  return YES;
}

@end

コードが実行されている理由を説明できますが、もちろんそれは非常に悪いことです。この問題が発生する可能性のある方法はありますか?

4

5 に答える 5

4

インスタンスが認識しないメッセージの送信に応答して、Objective-C ランタイムから直接例外が発生することはありません。これは-[NSObject doesNotRecognizeSelector:]、さまざまなメソッド ルックアップおよび転送メカニズムの最後に呼び出される から取得されます。

ただし、必要なときに何でも呼び出すことができ-doesNotRecognizeSelector:ます。クラスは、継承されたメソッドをオーバーライドし、そのオーバーライドを単に invoke にすることで、継承されたメソッドを「否認」できます-doesNotRecognizeSelector:文書化されているように、これにより、 -respondsToSelector:(および+instancesRespondToSelector:) が返されるにもかかわらず、例外が発生しますYES

__NSCFStringエンドユーザーの場合、なぜそうしているのかわかりませんでした。ライブラリを使用しているアプリは、そのクラスのメソッドを変更するためにカテゴリまたはメソッドの入れ替えを使用していますか?

また、ログに例外の実際のスタック トレース キャプチャが表示されますか? それは有益かもしれません。

于 2013-04-24T03:36:13.847 に答える
4

サードパーティのライブラリを正しい方法でインポートしなかったと思います。通常、このメソッドはカテゴリとして NSString に追加されます。たまたま .h ファイルは表示されましたが、.m はコンパイルされていませんでした。xcodeターゲット内で確認できます->ビルドフェーズ->ソースをコンパイルします。または、プロジェクト内でこのフラグを使用しているかどうかを確認します-->ビルド設定-->その他のリンカー フラグ =-all_load

于 2013-04-11T06:09:35.583 に答える
0

奇妙な可能性があります。それperformSelector自体が、コードの残りの部分とは異なるリンクロード環境で何らかの形で実行されている可能性があります。ただし、これがどのように発生するかは正確には(またはおおよそでも)わかりません。

于 2013-04-18T02:34:36.910 に答える