10

重複の可能性:
Objective-Cでのインターセプトメソッド呼び出し
iOSアプリで使用されるすべてのメソッドをログに記録する方法

たとえば、UIViewControlleriOSのオブジェクトは、そのビューがユーザーに表示される前に多くのメッセージを受信します。

  1. viewWillAppear
  2. viewWillLayoutSubviews
  3. viewDidLayoutSubviews
  4. viewDidAppear
  5. ..。

フレームワークのソースコードは表示できないため、書籍やブログに依存する必要があります。または、(1)Objective-C、または(2)任意のツールによってこのオブジェクトに送信されたすべてのメッセージを印刷または監視する方法があります。 ?

4

2 に答える 2

17

私のコメントではなく、私が使用した(そして今でも使用している)最善のアプローチは、次のように呼び出すことです。

(void)instrumentObjcMessageSends(YES);

すべてのメッセージのログ記録を開始する必要がある場合:

(void)instrumentObjcMessageSends(NO);

を追加することを忘れないでください#import <objc/runtime.h>
もういらない時。厄介なのは、ログが下/tmp/msgSends-に作成されることです。これは、ターミナルを開いてtail、読み取り可能な方法でログを表示するために使用する必要があることを意味します。

印刷されるものは次のようなものです。

- CustomTableViewController UIViewController _parentModalViewController
- CustomTableViewController UIViewController isPerformingModalTransition
- CustomTableViewController UIViewController setInAnimatedVCTransition:
- CustomTableViewController UIViewController viewWillMoveToWindow:
- CustomTableViewController UIViewController isPerformingModalTransition
- CustomTableViewController UIViewController parentViewController
- CustomTableViewController UIViewController _popoverController
- CustomTableViewController UIViewController _didSelfOrAncestorBeginAppearanceTransition
- CustomTableViewController UIViewController parentViewController
- CustomTableViewController UIViewController __viewWillDisappear:
- CustomTableViewController UIViewController _setViewAppearState:isAnimating:
- CustomTableViewController UIViewController automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers

注:このアプローチを最後に使用してからしばらく経ちましたが、このアプローチはサブクラス化されたプライベートメソッドをログに記録しないようです。したがって、DummyClasswith-(void)_dummyMethodがprivateで、次にDummySubClasswithが-(void)_dummyMethod実装されている場合、メッセージはログに記録されません。

iOSの場合、これはシミュレーターでのみ機能します。

于 2012-05-25T07:37:43.743 に答える
14

DTraceを使用して、実行中のアプリケーションを監視し、呼び出されたメソッドとクラスを確認できます。コマンドラインでDTraceを使用してシミュレータで実行されているiOSアプリを簡単に監視できます。まず、を使用してアプリケーションのPIDを見つける必要があります。ps次に、次のようにDTraceプローブを実行できます。

sudo dtrace -q -n 'objc1234:::entry { printf("%s %s\n", probemod, probefunc); }' 

ここで、1234はアプリのプロセスIDです。

これにより、次のような出力が生成されます。

UIStatusBarItemView -isVisible
UIStatusBarLayoutManager -_positionAfterPlacingItemView:startPosition:
UIView(Geometry) -frame
CALayer -frame
UIStatusBarLayoutManager -_startPosition
UIView(Geometry) -bounds
CALayer -bounds
UIStatusBarItemView -standardPadding
UIStatusBarItem -appearsOnLeft
UIStatusBarItem -leftOrder

たとえば、単一のクラスのトレースのみに関心がある場合はUIView、次を使用できます。

sudo dtrace -q -n 'objc1234:UIView::entry { printf("%s %s\n", probemod, probefunc); }'

deallocすべてのクラスのすべての呼び出しをトレースする場合は、次を使用します。

sudo dtrace -q -n 'objc1234::-dealloc:entry { printf("%s %s\n", probemod, probefunc); }'

UIView dealloc明らかに、これらを組み合わせてsのみを表示することができます。

sudo dtrace -q -n 'objc1234:UIView:-dealloc:entry { printf("%s %s\n", probemod, probefunc); }'

クラスの特定のオブジェクトを区別できるようにしたい場合はself、以下を使用してオブジェクトのメモリアドレス()を出力することもできます。

sudo dtrace -q -n 'objc1234:UIView:-dealloc:entry { printf("%s (0x%p) %s\n", probemod, arg0, probefunc); }'

DTraceは非常に強力で、ここで示したよりもかなり多くのことを実行できます。

于 2012-05-25T06:53:03.410 に答える