Цель-C: получение истинного класса классов в кластерах классов - PullRequest
2 голосов
/ 15 мая 2010

Недавно, пытаясь ответить на вопросы здесь, я запустил тестовый код, чтобы увидеть, как Xcode / gdb сообщил о классе экземпляров в кластерах классов . (см. ниже) В прошлом я ожидал увидеть что-то вроде:

PrivateClusterClass:PublicSuperClass:NSObject

Как это (который все еще возвращается, как ожидалось):

NSPathStore2:NSString:NSObject

... для строки, созданной с помощью +[NSString pathWithComponents:].

Однако с помощью NSSet и подкласса следующий код:

- (void)applicationDidFinishLaunching:(UIApplication *)application {    
    NSSet *s=[NSSet setWithObject:@"setWithObject"];
    NSMutableSet *m=[NSMutableSet setWithCapacity:1];
    [m addObject:@"Added String"];
    NSMutableSet *n = [[NSMutableSet alloc] initWithCapacity:1];
    [self showSuperClasses:s];
    [self showSuperClasses:m];
    [self showSuperClasses:n];
    [self showSuperClasses:@"Steve"];   
}

- (void) showSuperClasses:(id) anObject{
    Class cl = [anObject class];
    NSString *classDescription = [cl description];
    while ([cl superclass]) 
    {
        cl = [cl superclass];
        classDescription = [classDescription stringByAppendingFormat:@":%@", [cl description]];
    }
    NSLog(@"%@ classes=%@",[anObject class], classDescription);
}

... выходы:

// NSSet *s
NSCFSet classes=NSCFSet:NSMutableSet:NSSet:NSObject
//NSMutableSet *m
NSCFSet classes=NSCFSet:NSMutableSet:NSSet:NSObject
//NSMutableSet *n
NSCFSet classes=NSCFSet:NSMutableSet:NSSet:NSObject
// NSString @"Steve"
NSCFString classes=NSCFString:NSMutableString:NSString:NSObject

Отладчик показывает один и тот же класс для всех экземпляров Set. Я знаю, что в прошлом кластер классов Set не возвращался таким образом.

  1. Что изменилось? (Я подозреваю, что это изменение моста от Core Foundation.)
  2. Какой класс кластера сообщает просто общий класс, например NSCFSet и который сообщает фактический подкласс, например NSPathStore2?
  3. Самое главное, при отладке, как определить фактический класс экземпляра кластера NSSet?

1 Ответ

3 голосов
/ 15 мая 2010
  1. Детали реализации изменились, скорее всего, в связи с переходом на CF. Если вы посмотрите внимательно, то увидите, что в реализации CoreFoundation можно найти связку реализации Objective C, поддерживающей различные классы Foundation.

  2. Еще одна деталь реализации. Реализация кластеров классов Foundation меняется - иногда сильно, иногда незаметно - с каждым выпуском Mac OS X. Точный набор частных классов, связанных с упомянутой реализацией, как правило, отклоняется от любого конкретного набора требований, необходимых для достижения гибкого и разумно оптимальное решение при сохранении контракта API публичных классов.

  3. NSCFSet равен фактическому классу. Особенности экземпляров определяются тем, как вы распределили их в первую очередь. Не существует открытого способа определить, является ли ваш набор изменчивым или неизменным. Это на самом деле специально; Путь написания большого количества кода, который меняет поведение в зависимости от изменчивости кластера классов, приводит к безумию.

...