4

是否可以通过 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... 
4

0 回答 0