2009-12-11 10 views
6

अद्यतन मैंने Mark के सुझाव को लागू करके ओवरराइड विधियों के डुप्लिकेशन को समाप्त करने और संपत्ति या विधि के उत्प्रेरक को ट्रैक करने के लिए कोड को ठीक किया। अभी तक संपत्ति प्रकारों का सामना नहीं किया है (जब मैं करता हूं तो शायद property_getAttributes() से शुरू होगा)। वेस्टिगियल अंडरस्कोर भी छीन लिया।मैं उद्देश्य-सी में कक्षा का निरीक्षण कैसे करूं?


मूल रूप से मैं अपने आप को याद दिलाने के लिए कोई तरीका होना चाहिए क्या तरीकों और गुण विरासत पेड़ नीचे सभी तरह हॉपिंग के बिना उसकी वस्तु पर उपलब्ध हैं।

मैं निम्नलिखित समारोह अप पकाया है, लेकिन यह वांछित होने के लिए एक सा छोड़ देता है:

#import <objc/runtime.h> 

NSInteger inspectClass_alphabeticSort(id string1, id string2, void *reverse) 
{ 
    if ((NSInteger *)reverse == NO) 
    { 
     return [string2 localizedCaseInsensitiveCompare:string1]; 
    } 
    return [string1 localizedCaseInsensitiveCompare:string2]; 
} 

void inspectClassStopAt(Class inspectedClass, Class stopClass) 
{ 
    Class originalClass    = inspectedClass; 
    NSString *originalClassString = [NSString stringWithFormat:@"%@", originalClass]; 
    NSString *inheritancePath  = [NSString stringWithFormat:@"%@", originalClass]; 

    Method *methods; 
    objc_property_t *properties; 
    unsigned int i; 
    unsigned int methodCount; 
    unsigned int propertyCount; 
    int reverseSort = NO; 

    NSArray *sorted; 
    NSArray *methodsAndPropertiesKeys; 
    NSMutableDictionary * methodsAndProperties = [NSMutableDictionary dictionaryWithCapacity:10]; 

    NSString *inspectedClassString; 
    NSString *methodOrPropertyName; 
    while (inspectedClass != stopClass) 
    { 
     inspectedClassString = [NSString stringWithFormat:@"%@", inspectedClass]; 
     if (inspectedClass != originalClass) 
     { 
      inheritancePath = [inheritancePath stringByAppendingFormat:@" : %@", inspectedClass]; 
     } 

     methods  = class_copyMethodList(inspectedClass, &methodCount); 
     properties = class_copyPropertyList(inspectedClass, &propertyCount); 

     for (i=0; i<methodCount; i++) 
     { 
      methodOrPropertyName = [NSString stringWithFormat:@"-%s", sel_getName(method_getName(methods[i]))]; 

      if (![methodsAndProperties objectForKey:methodOrPropertyName]) 
      { 
       [methodsAndProperties setObject:inspectedClassString forKey:methodOrPropertyName]; 
      } 
     } 

     for (i=0; i<propertyCount; i++) 
     { 
      methodOrPropertyName = [NSString stringWithFormat:@" %s", property_getName(properties[i])]; 

      if (![methodsAndProperties objectForKey:methodOrPropertyName]) 
      { 
       [methodsAndProperties setObject:inspectedClassString forKey:methodOrPropertyName]; 
      } 
     } 

     inspectedClass = [inspectedClass superclass]; 
    } 
    free(methods); 
    free(properties); 

    methodsAndPropertiesKeys = [methodsAndProperties allKeys]; 
    sorted = [methodsAndPropertiesKeys sortedArrayUsingFunction:inspectClass_alphabeticSort context:&reverseSort]; 

    NSLog(@"%@", inheritancePath); 
    for (NSString *key in sorted) 
    { 
     if (![[methodsAndProperties objectForKey:key] isEqualToString:originalClassString]) 
     { 
      NSLog(@"\t%@ (%@)", key, [methodsAndProperties objectForKey:key]); 
     } 
     else 
     { 
      NSLog(@"\t%@", key); 
     } 
    } 
} 

void inspectClass(Class inspectedClass) 
{ 
    inspectClassStopAt(inspectedClass, [NSObject class]); 
} 

और inspectClass([TextMap class]); से कुछ नमूना उत्पादन:

TextMap : Surface 
    position (Surface) 
    size (Surface) 
    -addChild: (Surface) 
    -dealloc 
    -init (Surface) 
    -initWithFile: 
    -position (Surface) 
    -render 
    -setPosition: (Surface) 
    -setSize: (Surface) 
    -setText: 
    -size (Surface) 
    -update (Surface) 
+0

इसके लिए उपयोग का क्या मामला है? मैं इसे डीबगर कंसोल में उपयोगी पाया जा सकता था, सिवाय इसके कि, आप एक ही जानकारी प्राप्त करने के लिए कोड पूर्ण कर सकते हैं। –

+0

मैं अभी भी उद्देश्य-सी के लिए अपेक्षाकृत नया हूं इसलिए मैं पुनरावृत्ति कर रहा हूं। बहुत। कोड को सुधारने या दोबारा सुधारने के लिए नहीं बल्कि इसे काम करने के लिए। गुण और विधि हस्ताक्षर मेरी मूल अपेक्षाओं और डिजाइन से बहुत कुछ बदलते हैं। एक स्पष्ट तस्वीर को एक साथ टुकड़े करने के लिए तीन या चार स्रोत फ़ाइलों को मारने के बिना बस कक्षा के वर्तमान हस्ताक्षर को डंप करने में सक्षम होना अच्छा लगेगा। NSObject से विरासत में प्राप्त सभी गैर-विशिष्ट विधियों और गुणों के कारण कोड पूर्णता मेरे लिए काम नहीं करती है। –

+0

ऐसा लगता है कि इस प्रश्न का उत्तर प्रश्न में है! अच्छा काम। इससे मुझे एक टन में मदद मिली। – levous

उत्तर

1

आपको क्या चाहिए एक NSMutableDictionary है की तरह लगता है , चयनकर्ता नामों पर कुंजी। श्रेणी के नाम के साथ मूल्य के साथ प्रत्येक चयनकर्ता नाम को कुंजी के रूप में शब्दकोश में जोड़ें। डुप्लिकेट को खत्म करने के लिए, आप चयनकर्ता जोड़ने से पहले शब्दकोश को खोज सकते हैं।

2

एक अच्छा सहायक/runtime.h के साथ प्रदान की ग पुस्तकालयों के लिए आवरण https://github.com/mikeash/MAObjCRuntime

मैं सिर्फ इसका इस्तेमाल करने शुरू कर है लेकिन यह निश्चित रूप होनहार लग रहा है।

जहां तक ​​उपयोग के मामले में, मेरा एक स्वयं वायरिंग यूआई बनाने के लिए इंस्पेक्टर प्रदान करना है जिसे किसी ऑब्जेक्ट ग्राफ़ से जोड़ा जा सकता है। यह संभावित डुप्लिकेट कोड कमी का बहुत कुछ है।

संबंधित मुद्दे