最近,在尝试在此处回答问题时,我运行了一些测试代码以查看Xcode / gdb如何报告class clusters中的实例类。 (请参见下文)过去,我曾期望看到类似以下内容的东西:

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类集群不会像这样返回。


有什么变化? (我怀疑这是与Core Foundation的桥梁发生的变化。)
什么类集群仅报告通用类,例如NSCFSet并报告实际的子类,例如NSPathStore2?
最重要的是,在调试时如何确定NSSet群集实例的实际类?

最佳答案

实现细节的更改很可能与桥接到CF有关。如果仔细观察,您会发现现在可以在CoreFoundation中找到许多支持各种Foundation类的Objective-C实现。
另一个实现细节。随着Mac OS X的每个发行版,Foundation类群集的实现都会发生更改(有时会很大,有时会微妙)。与该实现相关的私有类的确切集合通常是实现灵活的任何特定需求集的结果。合理的最佳解决方案,同时还保留了面向公众的类的API合同。
NSCFSet是实际的类。实例的功能取决于您首先如何分配实例。没有公开的方法可以确定您的集合是可变的还是不可变的。这实际上是故意的;沿着编写大量基于类集群的可变性来改变行为的代码的道路上,会导致疯狂。

关于iphone - Objective-C:在类集群中获取真正的类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2840972/

10-09 01:49