1

Objective-C を研究するとき、その高度なダイナミズムの結果の 1 つは、実行時にオブジェクトが応答しなくても、オブジェクトに任意のメッセージを送信できることです。

その後、メッセージを無視して例外を発生させます。

実際のケースでは、デリゲートに実装されていないデリゲート オブジェクトにメッセージを送信しようとしています。

もちろん、機能を実装するには実装する必要がありますが、純粋に興味がないので、そうしないとアプリケーションがクラッシュするのはなぜだろうと思っていました。

2011-06-05 17:44:39.280 myTest[28158:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TVC DoneLoadingNoStoriesFound:]: unrecognized selector sent to instance 0x5c0ef90'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x015cabe9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x0171f5c2 objc_exception_throw + 47
    2   CoreFoundation                      0x015cc6fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x0153c366 ___forwarding___ + 966
    4   CoreFoundation                      0x0153bf22 _CF_forwarding_prep_0 + 50
    5   myTest                             0x0003db93 -[Loader loadTasksForStoriesForDisplayedWorkpace] + 1268
    6   myTest                             0x0003d388 -[Loader requestFinished:] + 1936
    7   myTest                             0x00017f2e -[ASIHTTPRequest reportFinished] + 100
    8   Foundation                          0x001f69a6 __NSThreadPerformPerform + 251
    9   CoreFoundation                      0x015ac01f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    10  CoreFoundation                      0x0150a28b __CFRunLoopDoSources0 + 571
    11  CoreFoundation                      0x01509786 __CFRunLoopRun + 470
    12  CoreFoundation                      0x01509240 CFRunLoopRunSpecific + 208
    13  CoreFoundation                      0x01509161 CFRunLoopRunInMode + 97
    14  GraphicsServices                    0x01b0f268 GSEventRunModal + 217
    15  GraphicsServices                    0x01b0f32d GSEventRun + 115
    16  UIKit                               0x0048642e UIApplicationMain + 1160
    17  myTest                             0x0000272b main + 85
    18  myTest                             0x000026cd start + 53
)
terminate called after throwing an instance of 'NSException'
Program received signal:  “SIGABRT”.
kill
quit
4

5 に答える 5

2

認識されないセレクターを受け取るオブジェクトのデフォルトの動作は例外をスローするため、クラッシュしました。

また、例外をキャッチする @try / @catch ブロックがない場合、キャッチされない例外によってアプリケーションが終了します。

ただし、認識されないセレクターを処理するメソッドをオーバーライドすることで、このデフォルトの動作を変更できます。これらの NSObject メソッドをチェックしてください:

  • forwardingTargetForSelector:
  • resolveInstanceMethodDynamically:
  • forwardInvocation:
  • セレクターを認識しない:

また、Mike Ash によるすばらしい記事もここにあり、全体的な概要がよくわかります。

ダイナミズムがもたらす違いは、認識されていないセレクターに対して例外をスローすることです。これにより、(セグメンテーション違反ですぐに終了するのではなく) エラーへの対応方法を決定できます。オブジェクトが認識されていないセレクターにどのように応答するかをオーバーライドするオプションもあります。ただし、通常は何か間違ったことをした兆候であるため、ほとんどの場合、例外をスローする必要があります。

于 2011-06-05T16:12:48.933 に答える
1

すでに述べたように、応答できないオブジェクトにメッセージを送信しようとしています。デリゲートの場合、メッセージを送信する前にセレクターに応答するかどうかを確認することは理にかなっています。そのチェックは次のようになります。

if ( [delegate respondsToSelector:@selector(DoneLoadingNoStoriesFound:)] ) {
    [delegate DoneLoadingNoStoriesFound:YES];
}
于 2011-06-05T16:35:04.633 に答える
0

私が何かを見逃していない限り、あなたが指摘したように例外がスローされますが、それをキャッチする場所がないため、アプリケーションは終了します。

于 2011-06-05T16:12:18.570 に答える
0

if ( [delegate respondsToSelector:@selector(DoneLoadingNoStoriesFound:)] ) { [delegate DoneLoadingNoStoriesFound:YES]; }デリゲートにメッセージを送信するときはいつでも、などの良い習慣を作ります。

于 2015-12-23T09:57:34.463 に答える