为什么在OS X上有[@""class]!= NSClassFromString(NSStringFromClass([@""class]))?

Kai*_*udi 10 cocoa operating-system objective-c

if([@"" class] == NSClassFromString(NSStringFromClass([@"" class])))
    printf("foo");
else
    printf("bar");
Run Code Online (Sandbox Code Playgroud)

iOS上的输出:foo

OS X上的输出:bar

为什么这在OS X上表现得如此奇怪?

rma*_*ddy 9

有趣的问题.以下指出评论中提到的一些事项:

Class c1 = [@"" class];
Class c2 = NSClassFromString(NSStringFromClass([@"" class]));

// The names are the same under iOS and OS X
NSLog(@"c1: '%@', c2: '%@'", c1, c2);
// The pointers are the same under iOS but different under OS X
NSLog(@"*c1: '%p', *c2: '%p'", c1, c2);

if (c1 == c2) {
    NSLog(@"== equal"); // iOS
} else {
    NSLog(@"== not equal"); // OS X
}

if ([c1 isEqual:c2]) {
    NSLog(@"isEqual: equal"); // iOS
} else {
    NSLog(@"isEqual: not equal"); // OS X
}

const char *n1 = class_getName(c1);
const char *n2 = class_getName(c2);
if (strcmp(n1, n2) == 0) {
    NSLog(@"name equal"); // Both iOS and OS X
} else {
    NSLog(@"name not equal");
}
Run Code Online (Sandbox Code Playgroud)

在Mac(OS X 10.7.5)上,这给出了:

2013年5月7日12:35:45.249试验[27483:303] C1: '_ NSCFConstantString',C2: ' _NSCFConstantString'
2013年5月7日12:40:06.673试验[27542:303]*C1: '0x7fff7d2bd740' ,*c2:'0x7fff7d28ae48'2013-05-07
12:35:45.250测试[27483:303] ==不等于
2013-05-07 12:35:45.251测试[27483:303] isEqual:not equal
2013-05 -07 12:35:45.251测试[27483:303]名称相等

在iOS(6.1)上,这给出了:

2013年5月7日12:38:11.816试验[27516:11303] C1: '_ NSCFConstantString',C2: ' _NSCFConstantString'
2013年5月7日12:41:01.319试验[27557:11303]*C1: '0x1db88f8' ,*c2:'0x1db88f8'2013-05-07
12:38:11.816 测试[27516:11303] ==等于
2013-05-07 12:38:11.816测试[27516:11303] isEqual:相等
2013-05-07 12:38:11.816测试[27516:11303]名称相等

关键的区别似乎是在iOS下,这两个Class值是相同的对象,但在OS X下它们是两个不同的对象.

因此,Class使用==或比较两个值似乎是不安全的isEqual:,至少在OS X下.我找不到任何比较两个Class值的函数,所以使用class_getName似乎是最好的选择.

  • 然而,就问题而言,原因很简单:类是对象,并且可以有多个实例.甚至可以让类伪装成其他类(KVO类一直这样做),使它们完全不同但看起来是一样的.除了自己,你不能使用`==`将对象与任何东西进行比较.也就是说,我实际上有点惊讶`isEqual:`失败,但是然后Classes是对象,但不是*ObjC中的*对象.:D他们有点像物体. (2认同)