क्या उद्देश्य-सी में किसी ऑब्जेक्ट को भेजे गए संदेशों की निगरानी या मुद्रित किया जा सकता है?

संभावित डुप्लिकेट:
   उद्देश्य-सी में इंटरसेप्ट विधि कॉल
   आईओएस ऐप में उपयोग की जाने वाली सभी विधियों को कैसे लॉग करें

उदाहरण के लिए, आईओएस में एक UIViewController ऑब्जेक्ट को उपयोगकर्ता को इसके दृश्य को दिखाए जाने से पहले कई संदेश प्राप्त होते हैं:

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

क्योंकि ढांचे का स्रोत कोड देखने योग्य नहीं है, हमें पुस्तकों या ब्लॉगों पर भरोसा करना है, या किसी ऑब्जेक्ट द्वारा ऑब्जेक्टिव-सी, या (2) द्वारा इस ऑब्जेक्ट को भेजे गए सभी संदेशों को प्रिंट या मॉनीटर करने का कोई तरीका है ?

10
जोड़ा संपादित
विचारों: 2
@trojanfoe: अच्छा खोज। यह ध्यान दिया जाना चाहिए कि स्वीकार्य उत्तर नहीं करेगा क्या करें (मुझे विश्वास है) 動靜 能量 पूछ रहा है क्योंकि इसे अग्रिम में जाने की विधि की आवश्यकता है, लेकिन या तो ओले बेगमैन या emp's उत्तर काम करेगा।
जोड़ा लेखक Josh Caswell, स्रोत
असल में, मैं अनिवार्य रूप से एएमपी के समाधान का सुझाव देने जा रहा था।
जोड़ा लेखक Josh Caswell, स्रोत
यह एक डुप्लिकेट नहीं है, वह सभी विधियों को रोकने के लिए कह रहा है, केवल एक नहीं ... यहां स्विजलिंग का उपयोग करके पूरे वर्ग को फिर से कार्यान्वित करना है।
जोड़ा लेखक bontoJR, स्रोत

2 उत्तर

मेरी टिप्पणी के बजाय, मैंने उपयोग किया जाने वाला सबसे अच्छा तरीका (और अभी भी उपयोग) कॉल कर रहा है:

(void)instrumentObjcMessageSends(YES);

जब मुझे सभी संदेशों को लॉगिंग शुरू करने की आवश्यकता होती है और फिर:

(void)instrumentObjcMessageSends(NO);

Don't forget to add #import .
When I don't need it anymore. The annoying thing is that the log is created under /tmp/msgSends- and this means that you have to open the terminal and use tail to see it in a readable way.

मुद्रित क्या है इस तरह कुछ है:

- 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

नोट: यह थोड़ी देर हो गया है क्योंकि मैंने पिछली बार इस दृष्टिकोण का उपयोग किया था और ऐसा लगता है कि यह दृष्टिकोण निजी विधियों को उप-वर्गीकृत नहीं करता है। इसलिए, यदि आपके पास - (शून्य) _dummyMethod के साथ - (void) _dummyMethod के साथ DummySubClass के साथ DummyClass है कार्यान्वयन, संदेश लॉग नहीं किया जाएगा।

आईओएस के लिए, यह केवल सिम्युलेटर पर काम करता है।

14
जोड़ा
+1 बहुत अच्छा लगता है।
जोड़ा लेखक Rog, स्रोत
आप प्रतीकात्मक ब्रेकपॉइंट्स का उपयोग करके कुछ भी ऐसा कर सकते हैं, जैसा कि मैंने यह उत्तर में वर्णित किया है, और मेरा मानना ​​है कि यह भी काम करेगा डिवाइस अगर आप मेमोरी पतों को उचित रूप से समायोजित करते हैं।
जोड़ा लेखक Brad Larson, स्रोत
@ एच 2CO3: केवल सिम्युलेटर पर काम करता है, इसे इंगित करने के लिए धन्यवाद, मैं नोट जोड़ दूंगा।
जोड़ा लेखक bontoJR, स्रोत

विधियों और वर्गों को देखने के लिए आप चल रहे एप्लिकेशन की निगरानी के लिए डीटीआरई का उपयोग कर सकते हैं। आप आसानी से कमांड लाइन पर डीटीआरएस का उपयोग कर सिम्युलेटर में चल रहे आईओएस ऐप की निगरानी कर सकते हैं, सबसे पहले आपको ps का उपयोग करके एप्लिकेशन के पीआईडी ​​को ढूंढना होगा और फिर आप निम्नलिखित की तरह डीटी्रेस जांच चला सकते हैं:

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

जहां 1234 ऐप की प्रक्रिया आईडी है।

यह आउटपुट उत्पन्न करेगा जो निम्न जैसा दिखता है:

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); }'

डीटी्रेस बेहद शक्तिशाली है और यहां दिखाए गए से काफी कुछ कर सकता है।

14
जोड़ा
आप इसके लिए एक कस्टम उपकरण भी बना सकते हैं, जिसका उदाहरण मैं यह आलेख MacResearch पर खत्म हो गया
जोड़ा लेखक Brad Larson, स्रोत
मैं मानता हूं कि डीटी्रेस शक्तिशाली है। कुछ सुझाव: श्रेणियों में परिभाषित विधियों को पकड़ने के लिए कक्षा के बाद वाइल्डकार्ड का उपयोग करें। प्रिंटआउट में tid शामिल करें। टाइमस्टैम्प भी शामिल करें। समस्या यह है कि डीटी्रेस आदेश से डेटा प्राप्त कर सकता है और आपको आदेश को पुनर्निर्माण करना पड़ सकता है। आपको विभिन्न धागे से धाराओं को अलग करना भी पड़ सकता है। यह संग्रहीत ईमेल संलग्न संलग्न स्क्रिप्ट के साथ देखें यह प्लस थ्रेड के भीतर कॉल गहराई को ट्रैक करता है। य
जोड़ा लेखक Ken Thomases, स्रोत
@ केन थॉमस उत्कृष्ट अंक और मुझे संलग्न लिपि पसंद है
जोड़ा लेखक mttrb, स्रोत