Objective-C:获取类簇中类的真实类
最近,当试图在这里回答问题时,我运行了一些测试代码来查看 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类簇不是这样返回的。
- 发生了什么变化? (我怀疑这是 Core Foundation 桥接器的更改。)
- 哪些类簇仅报告通用类(例如 NSCFSet),哪些类簇报告实际子类(例如 NSPathStore2)?
- 最重要的是,在调试时如何确定 NSSet 集群实例的实际类?
Recently while trying to answer a questions here, I ran some test code to see how Xcode/gdb reported the class of instances in class clusters. (see below) In the past, I've expected to see something like:
PrivateClusterClass:PublicSuperClass:NSObject
Such as this (which still returns as expected):
NSPathStore2:NSString:NSObject
... for a string created with +[NSString pathWithComponents:]
.
However, with NSSet and subclass the following code:
- (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);
}
... outputs:
// 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
The debugger shows the same class for all Set instances. I know that in the past the Set class cluster did not return like this.
- What has changed? (I suspect it is a change in the bridge from Core Foundation.)
- What class cluster report just a generic class e.g. NSCFSet and which report an actual subclass e.g. NSPathStore2?
- Most importantly, when debugging how do you determine the actual class of a NSSet cluster instance?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实施细节的更改很可能与 CF 桥接相关。如果仔细观察,您会发现现在可以在 CoreFoundation 中找到支持各种 Foundation 类的一堆 Objective-C 实现。
另一个实现细节。基础类簇的实现随着 Mac OS X 的每次发布而发生变化——有时很大,有时很微妙。与所述实现相关的私有类的确切集合通常是由实现灵活的系统所需的任何特定需求集决定的。合理的最佳解决方案,同时还保留面向公众的类的 API 契约。
NSCFSet是实际的类。实例的功能首先取决于您如何分配它。没有公开的方法来确定您的集合是可变的还是不可变的。这实际上是故意的;编写大量基于类簇的可变性来改变行为的代码会导致疯狂。
An implementation detail changed most likely related to the bridging to CF. If you look closely, you'll see that a bunch of the Objective-C implementation backing various Foundation classes can now be found in CoreFoundation.
Another implementation detail. The implementation of the Foundation class clusters change -- sometimes greatly, sometimes subtly -- with each release of Mac OS X. The exact set of private classes related to said implementation is generally fallout from whatever particular set of requirements were needed to achieve a flexible and reasonably optimal solution while also preserving the API contract of the public facing classes.
NSCFSet is the actual class. The features of the instances are determined by how you allocated it in the first place. There is no exposed way to determine if your set is mutable or immutable. This is actually on purpose; going down the path of writing a lot of code that changes behavior based on the mutability of a class cluster leads to madness.