为啥说 NSString 的可变副本等于原始不可变副本?
Posted
技术标签:
【中文标题】为啥说 NSString 的可变副本等于原始不可变副本?【英文标题】:Why a mutable copy of a NSString is said to be equal to the original immutable one?为什么说 NSString 的可变副本等于原始不可变副本? 【发布时间】:2014-01-07 06:08:30 【问题描述】:假设我有一个 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
所以这里出现了混乱,根据NSString
中isEqual
的文档,它是returns a Boolean value that indicates whether the receiver and a given object are equal
。那么为什么说可变副本与原来的不可变副本相同呢?
提前致谢!
【问题讨论】:
isEqual
比较的是字符,而不是指针引用,因此它们将相等,直到您改变 str2
。另见***.com/questions/3703554/…
【参考方案1】:
有(至少)三个独立的概念都可以被认为是“平等”:
-
“身份”(我和其他对象是同一个对象吗?)
“平等”(我与其他对象完全一样吗?)
“值相等”(我的值是否与其他对象相同?)
对于 ObjC 对象,您使用 ==
测试相同的身份,但使用 isEqual:
测试相同的值。没有用于测试精确相等性的一站式方法;一般来说,它并不是很有用。
在 javascript 中(为了比较),您使用 ===
测试相同的身份,使用 ==
测试等效值。同样没有直接的方法来测试完全相等。
对于像 int 和 float 这样的按值传递类型,没有身份这样的东西,因为您不能传递特定的实例。但是,如果你眯着眼睛,你可以认为这是不同类型具有相同值的类似情况:
int x = 5;
short y = 5;
if (x == y)
...
虽然在这种情况下它不是子类型关系。
【讨论】:
【参考方案2】:isEqual 比较两个字符串的内容,而不是它们的类型或标识。内容相等,因此它的评估结果为真。
要比较类型,请尝试:
if([str1 isKindOfClass:[str2 class]])
NSLog(@"same");
else
NSLog(@"different");
您应该会看到“不同”被记录下来。
【讨论】:
这对于字符串来说可能比较棘手,因为 NSCFString(NSString 的私有子类)可以用于可变字符串和不可变字符串。【参考方案3】:它们与字符串一样,但是是具有不同地址的不同对象。因此,isEqual
返回YES
,但与==
的比较结果为NO
。
【讨论】:
以上是关于为啥说 NSString 的可变副本等于原始不可变副本?的主要内容,如果未能解决你的问题,请参考以下文章