Why is [@“” class] != NSClassFromString(NSStringFromClass([@“” class])) on OS X?

前端 未结 1 1195
星月不相逢
星月不相逢 2021-01-02 07:00
if([@\"\" class] == NSClassFromString(NSStringFromClass([@\"\" class])))
    printf(\"foo\");
else
    printf(\"bar\");

Output on iOS: foo

1条回答
  •  一生所求
    2021-01-02 07:27

    Interesting issue. The following points out some things mentioned in the comments:

    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");
    }
    

    On a Mac (OS X 10.7.5) this gives:

    2013-05-07 12:35:45.249 Test[27483:303] c1: '_NSCFConstantString', c2: '_NSCFConstantString'
    2013-05-07 12:40:06.673 Test[27542:303] *c1: '0x7fff7d2bd740', *c2: '0x7fff7d28ae48'
    2013-05-07 12:35:45.250 Test[27483:303] == not equal
    2013-05-07 12:35:45.251 Test[27483:303] isEqual: not equal
    2013-05-07 12:35:45.251 Test[27483:303] name equal

    On iOS (6.1) this gives:

    2013-05-07 12:38:11.816 Test[27516:11303] c1: '_NSCFConstantString', c2: '_NSCFConstantString'
    2013-05-07 12:41:01.319 Test[27557:11303] *c1: '0x1db88f8', *c2: '0x1db88f8'
    2013-05-07 12:38:11.816 Test[27516:11303] == equal
    2013-05-07 12:38:11.816 Test[27516:11303] isEqual: equal
    2013-05-07 12:38:11.816 Test[27516:11303] name equal

    The key difference seems to be that under iOS, the two Class values are the same object but under OS X they are two different objects.

    So it seems it is not safe to compare two Class values using == or isEqual:, at least under OS X. I couldn't find any function to compare two Class values so using class_getName seems like the best alternative.

    0 讨论(0)
提交回复
热议问题