IBActionをxibファイルのボタンに接続するとします。アプリが実行されたら、ボタンをタップします。アクションは同期的に呼び出されますか、それともrunloopにperformSelectorリクエストが送信されますか?
質問する
358 次
1 に答える
2
同期です。
iOSアプリケーションでは、バックトレースは次のようになります。
frame #0: 0x000025d2 MyApp`-[ViewController myAction:] + 34 at ViewController.m:31
frame #1: 0x010e2705 libobjc.A.dylib`-[NSObject performSelector:withObject:withObject:] + 77
frame #2: 0x00019920 UIKit`-[UIApplication sendAction:to:from:forEvent:] + 96
frame #3: 0x000198b8 UIKit`-[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
frame #4: 0x000da671 UIKit`-[UIControl sendAction:to:forEvent:] + 66
frame #5: 0x000dabcf UIKit`-[UIControl(Internal) _sendActionsForEvents:withEvent:] + 578
frame #6: 0x000d9d38 UIKit`-[UIControl touchesEnded:withEvent:] + 546
frame #7: 0x0004933f UIKit`-[UIWindow _sendTouchesForEvent:] + 846
frame #8: 0x00049552 UIKit`-[UIWindow sendEvent:] + 273
frame #9: 0x000273aa UIKit`-[UIApplication sendEvent:] + 436
frame #10: 0x00018cf8 UIKit`_UIApplicationHandleEvent + 9874
frame #11: 0x01becdf9 GraphicsServices`_PurpleEventCallback + 339
frame #12: 0x01becad0 GraphicsServices`PurpleEventCallback + 46
frame #13: 0x01c06bf5 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
frame #14: 0x01c06962 CoreFoundation`__CFRunLoopDoSource1 + 146
frame #15: 0x01c37bb6 CoreFoundation`__CFRunLoopRun + 2118
frame #16: 0x01c36f44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #17: 0x01c36e1b CoreFoundation`CFRunLoopRunInMode + 123
frame #18: 0x01beb7e3 GraphicsServices`GSEventRunModal + 88
frame #19: 0x01beb668 GraphicsServices`GSEventRun + 104
frame #20: 0x0001665c UIKit`UIApplicationMain + 1211
frame #21: 0x00001f62 MyApp`main + 130 at main.m:16
frame #22: 0x00001e95 MyApp`start + 53
これは単純な同期コードです。アプリケーションはタッチエンドイベントを受信し、それをディスパッチする場所(ボタン)を特定し、ボタンのターゲットにメッセージを送信します。
対照的に、を介して非同期的に呼び出されるメソッド-[NSObject performSelector:withObject:afterDelay:]
には、次のようなバックトレースがあります。
frame #0: 0x00002628 MyApp`-[ViewController myAsyncAction:] + 24 at ViewController.m:37
frame #1: 0x00acce83 Foundation`__NSFireDelayedPerform + 380
frame #2: 0x01c50376 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
frame #3: 0x01c4fe06 CoreFoundation`__CFRunLoopDoTimer + 534
frame #4: 0x01c37a82 CoreFoundation`__CFRunLoopRun + 1810
frame #5: 0x01c36f44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #6: 0x01c36e1b CoreFoundation`CFRunLoopRunInMode + 123
frame #7: 0x01beb7e3 GraphicsServices`GSEventRunModal + 88
frame #8: 0x01beb668 GraphicsServices`GSEventRun + 104
frame #9: 0x0001665c UIKit`UIApplicationMain + 1211
frame #10: 0x00001f62 MyApp`main + 130 at main.m:16
frame #11: 0x00001e95 MyApp`start + 53
タイマーが起動してそのコールバックを呼び出し、その上に構築された「遅延実行」がトリガーされていることがはっきりとわかります。
于 2013-01-09T08:06:17.923 に答える