为什么NSString的可变副本被认为等于原始的不可变副本?

时间:2014-01-07 06:08:30

标签: objective-c

假设我有一个NSString * str1和NSMutableString * str2,我将str2作为str1的可变副本。我打电话给以下方法:

-(void)someMethod {
    NSString *str1;
    NSMutableString *str2;
    str1 = @"OK";
    str2 = [str1 mutableCopy];

    if ([str2 isEqual:str1]) {
        NSLog(@"Same!");
    }
    else {
        NSLog(@"Not exactly!");
    }

    NSLog(@"%@", [[str1 class] description]);
    NSLog(@"%@", [[str2 class] description]);
}

控制台输出:

2014-01-07 14:03:16.291 LearnFoundation[3739:303] Same!
2014-01-07 14:03:16.293 LearnFoundation[3739:303] __NSCFConstantString
2014-01-07 14:03:16.293 LearnFoundation[3739:303] __NSCFString

根据isEqualNSString的文档returns a Boolean value that indicates whether the receiver and a given object are equal,这里出现了混乱。那么为什么可变副本被认为与原始不可变副本相同? 提前谢谢!

3 个答案:

答案 0 :(得分:1)

isEqual比较两个字符串的内容,而不是它们的类型或标识。内容相同,因此评估为真。

要比较类型,请尝试:

if([str1 isKindOfClass:[str2 class]])
{ 
   NSLog(@"same");
}else{
   NSLog(@"different");
}

你应该看到“不同”被记录。

答案 1 :(得分:1)

有(至少)三个独立的概念都可以被认为是“平等”:

  1. “identity”(我和其他对象是同一个对象吗?)
  2. “相等”(我与其他对象完全相同吗?)
  3. “值相等”(我是否与其他对象具有相同的值?)
  4. 对于ObjC对象,您使用==测试同等身份,但使用isEqual:测试等效值。测试确切的平等没有一站式的商店方法;一般来说,结果证明它不是很有用。

    在Javascript中(为了便于比较),您使用===测试同等身份,并使用==测试等效值。同样没有直接的方法来测试确切的平等。

    对于像int和float这样的传值类型,没有身份这样的东西,因为你无法传递特定的实例。但是,如果您稍微眯一下,您可以将其视为具有相同值的不同类型的类似情况:

    int x = 5;
    short y = 5;
    if (x == y) {
        ...
    }
    

    虽然在这种情况下它不是子类型关系。

答案 2 :(得分:0)

它们与字符串相同,但是具有不同地址的不同对象。因此,isEqual会返回YES,但与==的比较会评估为NO