2015-06-23 1 views
0

Привет Я использую this answer, чтобы получить список классов для автоматической сборки некоторой структуры.Ошибка при обработке объекта класса __NSAtom

Мой код выглядит следующим образом:

NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity: 32]; 

Class* classes = NULL; 
int numClasses = objc_getClassList(NULL, 0); 
if (numClasses > 0) { 
    classes = (Class*)malloc(sizeof(Class) * numClasses); 
    numClasses = objc_getClassList(classes, numClasses); 
    for (int index = 0; index < numClasses; index++) { 
     Class nextClass = classes[index]; 

     if ([nextClass isSubclassOfClass: BaseCmd.class] && 
      ![BaseCmd isSubclassOfClass: nextClass]) { 
      BaseCmd *cmd = [nextClass new]; 
      result[cmd.name] = cmd; 
     } 
    } 
    free(classes); 
} 

return result; 

Так модификация с ответом довольно просто. Он отлично работает до тех пор, пока класс __NSAtom не обработан (index = 1548numClasses = 7628, так что это не выход из проблемы).

При достижении этого класса __NSAtom происходит сбой. Журналы показывают:

*** NSForwarding: warning: object 0x7fff74978938 of class '__NSAtom' does not implement methodSignatureForSelector: -- trouble ahead 
*** NSForwarding: warning: object 0x7fff74978938 of class '__NSAtom' does not implement doesNotRecognizeSelector: -- abort 

Крушение происходит от состояния isSubclassOfClass.

Почему это не работает? Как я могу это исправить?

Я использую OS X Yosemite.

+0

Вы должны использовать 'objc_copyClassList'. Это значительно более эффективно. (вместо того, чтобы дважды использовать мьютекс, он приобретает только один раз, а также множество условных ветвей). –

ответ

2

+[NSObject isSubclassOfClass:] - метод класса для NSObject, а не все классы являются подклассами NSObject.

Кажется, что у вас есть частный класс, который не является подклассом NSObject, поэтому для проверки наследования требуется более деликатная обработка. Попытка:

BOOL isSubclass(Class child, Class parent) { 
    for (Class c = child; c != Nil; c = class_getSuperclass(c)) { 
     if (c == parent) { 
      return YES; 
     } 
    } 
    return NO; 
} 
+1

'NSAtom' на самом деле не является приватным (в традиционном смысле)! Вы можете создать его, просто выделив целое число «1» объекту-c. Он имеет некоторые интересные свойства: http://brian-webster.tumblr.com/post/102637339374/the-mystery-of-the-crashing-nspredicate. Он также жестко закодирован в среду выполнения-c и немного задокументирован. –