Is it possible to access the arguments for the caller and the caller through the Obj-C runtime. I just found:
NSLog(@"%@", [NSThread callStackSymbols]);
I know this is possible, but are there any tools (APIs)?
UPDATE 1:
Perhaps we can analyze [NSThread callStackSymbols] to determine the number of arguments in each nested call. And then go through the stack ...
UPDATE 2:
I go deeper, [NSThread callStackSymbols] is:
0 MyApp 0x00009ee5 -[HNPViewController mapView:didDeselectAnnotationView:] + 117, 1 MapKit 0x00404d12 -[MKMapView annotationContainer:didDeselectAnnotationView:] + 100, 2 MapKit 0x00411f90 -[MKAnnotationContainerView _deselectAnnotationViewWithAnimation:tellDelegate:] + 204, 3 MapKit 0x003fef87 -[MKMapView handleTap:] + 544, 4 UIKit 0x007c485a _UIGestureRecognizerSendActions + 139, 5 UIKit 0x007c399b -[UIGestureRecognizer _updateGestureWithEvent:] + 333, 6 UIKit 0x007c50df -[UIGestureRecognizer _delayedUpdateGesture] + 46, 7 UIKit 0x007c7d2d ___UIGestureRecognizerUpdate_block_invoke_0543 + 57, 8 UIKit 0x007c7cac _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 331, 9 UIKit 0x007bfa28 _UIGestureRecognizerUpdate + 1348, 10 CoreFoundation 0x01870afe __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30, 11 CoreFoundation 0x01870a3d __CFRunLoopDoObservers + 381, 12 CoreFoundation 0x0184e7c2 __CFRunLoopRun + 1106, 13 CoreFoundation 0x0184df44 CFRunLoopRunSpecific + 276, 14 CoreFoundation 0x0184de1b CFRunLoopRunInMode + 123, 15 GraphicsServices 0x029097e3 GSEventRunModal + 88, 16 GraphicsServices 0x02909668 GSEventRun + 104, 17 UIKit 0x004f9ffc UIApplicationMain + 1211, 18 MyApp 0x0000281d main + 141, 19 MyApp 0x00002745 start + 53
And I type (id)*(&mapView+i) , where mapView is the first argument and i = 0 .. N:
(id)*(&mapView+0) = 0x09e55670 <MKMapView: 0x9e55670; frame = (0 0; 320 460); clipsToBounds = YES; autoresize = TM+BM; layer = <CALayer: 0x9e55720>> (id)*(&mapView+1) = 0x0046ec8f [no Objective-C description available] (id)*(&mapView+2) = 0x09e4bd90 <HNPViewController: 0x9e4bd90> (id)*(&mapView+3) = 0xe9a8b620 [no Objective-C description available] (id)*(&mapView+4) = 0x00000020 [no Objective-C description available] (id)*(&mapView+5) = 0x0046ec8f [no Objective-C description available] (id)*(&mapView+6) = 0x00000054 [no Objective-C description available] (id)*(&mapView+7) = 0xbfffda28 [no Objective-C description available] (id)*(&mapView+8) = 0x00404d12 [no Objective-C description available] (id)*(&mapView+9) = 0x09e4bd90 <HNPViewController: 0x9e4bd90> (id)*(&mapView+10) = 0x0046ec8f [no Objective-C description available] (id)*(&mapView+11) = 0x09e55670 <MKMapView: 0x9e55670; frame = (0 0; 320 460); clipsToBounds = YES; autoresize = TM+BM; layer = <CALayer: 0x9e55720>> (id)*(&mapView+12) = 0x14346af0 <MKUserLocationView: 0x14346af0; frame = (1.34202e+06 3.24204e+06; 23 23); layer = <MKUserLocationLayer: 0x1433b8f0>> accuracy:-1.000000 +37.78583400, -122.40641700 (id)*(&mapView+13) = 0x14346af0 <MKUserLocationView: 0x14346af0; frame = (1.34202e+06 3.24204e+06; 23 23); layer = <MKUserLocationLayer: 0x1433b8f0>> accuracy:-1.000000 +37.78583400, -122.40641700 (id)*(&mapView+14) = 0x00aa61d8 [no Objective-C description available] (id)*(&mapView+15) = 0x00000000 <nil> (id)*(&mapView+16) = 0x00411ed2 [no Objective-C description available] (id)*(&mapView+17) = 0x0aab0020 <MKAnnotationContainerView: 0xaab0020; frame = (0 0; 8.38861e+06 8.38861e+06); autoresizesSubviews = NO; layer = <CALayer: 0xaaaf810>> (id)*(&mapView+18) = 0x14346af0 <MKUserLocationView: 0x14346af0; frame = (1.34202e+06 3.24204e+06; 23 23); layer = <MKUserLocationLayer: 0x1433b8f0>> accuracy:-1.000000 +37.78583400, -122.40641700 (id)*(&mapView+19) = 0xbfffda58 [no Objective-C description available] [A] (id)*(&mapView+20) = 0x00411f90 [no Objective-C description available] (id)*(&mapView+21) = 0x09e55670 <MKMapView: 0x9e55670; frame = (0 0; 320 460); clipsToBounds = YES; autoresize = TM+BM; layer = <CALayer: 0x9e55720>> (id)*(&mapView+22) = 0x0046f3e3 [no Objective-C description available] (id)*(&mapView+23) = 0x0aab0020 <MKAnnotationContainerView: 0xaab0020; frame = (0 0; 8.38861e+06 8.38861e+06); autoresizesSubviews = NO; layer = <CALayer: 0xaaaf810>> (id)*(&mapView+24) = 0x14346af0 <MKUserLocationView: 0x14346af0; frame = (1.34202e+06 3.24204e+06; 23 23); layer = <MKUserLocationLayer: 0x1433b8f0>> accuracy:-1.000000 +37.78583400, -122.40641700 (id)*(&mapView+25) = 0x0aab0020 <MKAnnotationContainerView: 0xaab0020; frame = (0 0; 8.38861e+06 8.38861e+06); autoresizesSubviews = NO; layer = <CALayer: 0xaaaf810>> (id)*(&mapView+26) = 0x00000054 [no Objective-C description available] (id)*(&mapView+27) = 0x00000054 [no Objective-C description available] (id)*(&mapView+28) = 0x003fed75 [no Objective-C description available] (id)*(&mapView+29) = 0x09e55670 <MKMapView: 0x9e55670; frame = (0 0; 320 460); clipsToBounds = YES; autoresize = TM+BM; layer = <CALayer: 0x9e55720>> (id)*(&mapView+30) = 0x49a3d250 [no Objective-C description available] (id)*(&mapView+31) = 0xbfffdab8 [no Objective-C description available] [B] (id)*(&mapView+32) = 0x003fef87 [no Objective-C description available] (id)*(&mapView+33) = 0x0aab0020 <MKAnnotationContainerView: 0xaab0020; frame = (0 0; 8.38861e+06 8.38861e+06); autoresizesSubviews = NO; layer = <CALayer: 0xaaaf810>> (id)*(&mapView+34) = 0x0046ddfb [no Objective-C description available] (id)*(&mapView+35) = 0x00000001 [no Objective-C description available] (id)*(&mapView+36) = 0x00000001 [no Objective-C description available] (id)*(&mapView+37) = 0x00000001 [no Objective-C description available] (id)*(&mapView+38) = 0x433f8000 [no Objective-C description available] (id)*(&mapView+39) = 0xbfffdab8 [no Objective-C description available] (id)*(&mapView+40) = 0x015c85b4 [no Objective-C description available] (id)*(&mapView+41) = 0xbfffdaa0 [no Objective-C description available] (id)*(&mapView+42) = 0x49a3d250 [no Objective-C description available] (id)*(&mapView+43) = 0x4a45e070 [no Objective-C description available] (id)*(&mapView+44) = 0x00000000 <nil> (id)*(&mapView+45) = 0x0000000c [no Objective-C description available] (id)*(&mapView+46) = 0x00000054 [no Objective-C description available] (id)*(&mapView+47) = 0x41300000 [no Objective-C description available] (id)*(&mapView+48) = 0x43dc0000 [no Objective-C description available] (id)*(&mapView+49) = 0x41c00000 [no Objective-C description available] (id)*(&mapView+50) = 0x41300000 [no Objective-C description available] (id)*(&mapView+51) = 0x00000000 <nil> (id)*(&mapView+52) = 0x007c47dd [no Objective-C description available] (id)*(&mapView+53) = 0x0aaab070 <UITapGestureRecognizer: 0xaaab070; state = Ended; delaysTouchesEnded = NO; view = <UIView 0xaa93f00>; target= <(action=handleTap:, target=<MKMapView 0x9e55670>)>; must-fail = { <MKVariableDelayTapRecognizer: 0xaaad260; baseClass = UITapGestureRecognizer; state = Failed; view = <UIView 0xaa93f00>; target= <(action=handleDoubleTap:, target=<MKMapGestureController 0xaaadbe0>)>; numberOfTapsRequired = 2> }> (id)*(&mapView+54) = 0x00000004 [no Objective-C description available] (id)*(&mapView+55) = 0xbfffdb08 [no Objective-C description available] [C] (id)*(&mapView+56) = 0x007c485a [no Objective-C description available] (id)*(&mapView+57) = 0x09e55670 <MKMapView: 0x9e55670; frame = (0 0; 320 460); clipsToBounds = YES; autoresize = TM+BM; layer = <CALayer: 0x9e55720>> (id)*(&mapView+58) = 0x0046db75 [no Objective-C description available] (id)*(&mapView+59) = 0x132e7ce0 [no Objective-C description available] (id)*(&mapView+60) = 0x007c47dd [no Objective-C description available]
I added tokens [A], [B] and [C] in the lines where the address is equal to the address in callstack ...
UPDATE 3:
Using this code, I can determine if the user listened to my callout or not. I know that I should not use this code, but this is just for experiment :)
if ([(id)*(&mapView+53) isKindOfClass:[UIGestureRecognizer class]]) { CGPoint point = [(id)*(&mapView+53) locationInView:callout]; if (CGRectContainsPoint(callout.bounds, point)) { NSLog(@"Inside the callout"); } else { NSLog(@"Outside the callout"); } }