为什么NSString有时会使用等号?

时间:2012-02-06 00:04:25

标签: objective-c string nsstring identity equality

  

可能重复:
  Understanding NSString comparison in Objective-C

刚刚读到关于平等与身份的关系,我意识到在比较我的objc代码中的字符串时,我一直在使用一些相同的符号。奇怪的是,它实际上是时不时地工作,我想知道为什么。

http://www.karlkraft.com/index.php/2008/01/07/equality-vs-identity/

我有两段代码,一件是工作,一件不是。

WORKING。这里我有一个名为'Category'的对象,它有一个名为'name'的NSString属性。

@property (nonatomic, retain) NSString *name;

然后我有一个函数,我传入一个'Catergory'指针,当我在这里使用等号时,它完美地工作。

 -(void)addCategoryToStorage:(Category*)newcategory {
      if(newcategory.name != @"All") {  // this works

不工作。这里我使用NSFileManager调用的输出;

NSArray *dirContent = [self.fileManager 
                       contentsOfDirectoryAtPath:@"MyFiles"
                       error:nil];

然后我尝试比较数组中的NSStrings:

for(int i = 0; i < [dirContent count]; i++) { 
    if([dirContent objectAtIndex:i] == @"MyFile") // This will never be True

所以我的问题是,这两个NSString指针的工作方式有何不同?我知道我不应该使用“==”但此刻,但我很好奇为什么它有时会起作用。

我注意到他们调试之间有些区别。在第一种情况下,“newcategory”的“名称”表示(__ NSCFConstantString *)并且值可见。 由于某种原因,“dirContent”数组包含两个(__NSString *)对象,其中值不可见。

这提出了另一个问题。是什么让NSString在第一种情况下变成常量?当我将它传递给函数时,它似乎与它的创建方式有关。当我分配一个具有NSString属性的新对象然后我传入一个函数时,该函数将其视为一个常量(对象的NSString属性)。但是当对象存储在列表中并通过将[array objectAtIndex:index]传递给函数来获取它时,函数不会将其作为常量(对象的NSString属性)获取。

谢谢!

3 个答案:

答案 0 :(得分:5)

当指针指向同一个对象时,它可能会起作用。

如果代码中有字符串文字,则它实际上是NSString类型的静态分配对象。在代码中的任何一点,如果你要引用这个字符串值,你实际上使用的是同一个指针。 (指针基本上是一个内存地址)

如果代码中有多个字符串文字@"abc",则编译器只会放入一个实例,并使用指向此单个实例的指针。

这解释了为什么@"abc" == @"abc"

举个例子:

if(newcategory.name != @"All")
只有在您的代码中的某个时刻,

才会起作用:

newcategory.name = @"All";

如果你愿意的话

newcategory.name = [NSString stringWithFormat:@"%c%c%c",'A','l','l'];

因为在最后一种情况下你明确地分配了一个新的字符串。

编辑刚刚测试过,这个例子有缺陷:

newcategory.name = [NSString stringWithString:@"All"];

因为这已经过优化,所以指向@"All"

答案 1 :(得分:0)

当您与==进行比较时,您不是在比较字符串本身,而是将指针的值与字符串进行比较。在代码中声明字符串文字时,它们存储在可执行文件的data segment中。如果多个字符串变量指向相同的字符串文字,则它们可能指向相同的内存位置。

从文件加载字符串时,指针不能相等,因为它们可能不是来自可执行文件的数据段。

例如,两个字符串文字asdf通常只在可执行文件中存储一次,因此指针的值将相等。这是编译器执行的优化,但并不总是有效。

NSString* someVariable = @"asdf";

if(someVariable == @"asdf")
   NSLog(@"They are equal!");

答案 2 :(得分:0)

NString总是使用“==”符号,如果你想比较两个指针,看看它们是否引用了EXACT SAME对象。

短文字通常以这样的方式汇集,即使其中一个文字属于不同的类,也可能是@“ABC”== @“ABC”。

但不要指望它。