2009-12-11 45 views
6

更新我修正了代碼,以消除重複的重寫方法,並通過實施Mark的建議來追蹤屬性或方法的創建者。尚未處理屬性類型(我可能會從property_getAttributes()開始)。還刪除了殘留下劃線。如何檢查Objective-C中的類?


基本上我需要一種方法來提醒自己哪些方法和屬性都可以在給定對象上不跳一路下滑繼承樹。

我已經熟了以下的功能,但它留下了位不理想:

#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

這是什麼用例?我可以看到它在調試器控制檯中很有用,除此之外,您可以執行代碼完成來獲取相同的信息。 – 2009-12-12 07:35:59

+0

我還是比較新的Objective-C,所以我迭代。很多。不是爲了改進或重構代碼,而是爲了讓它工作。屬性和方法簽名從我原來的期望和設計中改變很多。如果能夠轉儲當前的班級簽名而無需打開三個或四個源文件來拼接清晰的圖片,那將會很好。代碼完成對我來說不起作用,因爲所有從NSObject繼承的非特定方法和屬性。 – 2009-12-12 14:46:54

+0

看起來這個問題的答案在這個問題上!工作很好。這幫了我很多忙。 – levous 2011-07-05 20:34:59

回答

1

好像你需要的是一個NSMutableDictionary ,鍵入選擇器名稱。將每個選擇器名稱作爲關鍵字添加到字典中,並將類名稱作爲值。您可以在添加選擇器之前搜索字典,以消除重複。

2

用於提供runtime.h C庫一個不錯的幫手/包裝是https://github.com/mikeash/MAObjCRuntime

我剛開始使用它,但它肯定看起來很有希望。

就用例而言,我只是簡單地提供一個檢查器來構建一個可以附加到對象圖上的自我佈線用戶界面。這是很多潛在的重複代碼減少。