刚刚读到关于平等与身份的关系,我意识到在比较我的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属性)获取。
谢谢!
答案 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”。
但不要指望它。