2013-01-09 104 views
0

说我连接一个IBAction与xib文件中的按钮。当应用程序运行时,我点击按钮,这个动作是同步调用还是在runloop上放入一个performSelector请求?Cocoa:IBAction回调是同步的还是异步的?

+1

在你的动作中设置一个断点。点击按钮,然后查看正在调用您的操作的回溯中的方法。它看起来像是被该代码同步调用的,还是看起来像是由延迟的'performSelector'调用的? –

+0

@KurtRevis我认为它是异步的,它看起来像“异步”,我只是想确保我在这里问。 – CarmeloS

回答

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 

你可以清楚地看到,一个计时器火灾和调用它的回调,而“延迟执行”在上面建那是被触发的。

+0

谢谢,但我认为performSelector是异步的,无论它是否有延迟参数。 performSelector是通过runloop拾取的,而不是CPU上的直接跳转指令,这就是我所说的异步,也许我们有一些误解。 – CarmeloS

+0

你在说什么'performSelector'方法? ' - [NSObject performSelector:]',并且具有一个或两个'object'参数的变体同步发生,而不经过运行循环。 [“performSelector:方法等同于直接向接收方发送aSelector消息。”](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject .html#// apple_ref/occ/intfm/NSObject/performSelector :)' - [NSObject performSelector:withObject:afterDelay:]'异步发生(当被运行循环触发时)。 –

+0

非常感谢你,我终于明白了。 performSelector在NSObject协议中定义,performSelector:afterDelay在NSObject类中。 – CarmeloS

相关问题