是否可以通过 Obj-C 运行时访问调用者和调用者的参数。我只发现:
NSLog(@"%@", [NSThread callStackSymbols]);
我知道这是可能的,但是有任何工具(API)吗?
更新 1:
也许我们可以分析[NSThread callStackSymbols]
以确定每个嵌套调用中的参数数量。然后穿过堆栈...
更新 2:
我要深入一点,[NSThread callStackSymbols]
是:
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
我正在打印(id)*(&mapView+i)
mapView 是第一个参数并且 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]
我在地址等于调用堆栈中的地址的行中添加了标记 [A]、[B] 和 [C]...
更新 3:
使用此代码,我可以确定用户是否点击了我的标注。我知道我不应该使用这段代码,但这只是为了实验:)
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");
}
}
// I have a problem not related to this question
// with callout right not, it closes after tap on it...