问题
Possible Duplicate:
Understanding NSString comparison in Objective-C
Was just reading up about equality vs identity and I realized that I've been using some equal signs when comparing strings in my objc code. The weird thing is that it actually works from times to times and I was wondering why.
http://www.karlkraft.com/index.php/2008/01/07/equality-vs-identity/
I have two pieces of code, one work and one doesn't.
WORKING. Here I have a object called 'Category' which has a NSString property called 'name'.
@property (nonatomic, retain) NSString *name;
I then have a function where I pass in a 'Catergory' pointer and when I use the equal sign here, it works perfectly.
-(void)addCategoryToStorage:(Category*)newcategory {
if(newcategory.name != @"All") { // this works
NON WORKING. Here I use the output from a NSFileManager call;
NSArray *dirContent = [self.fileManager
contentsOfDirectoryAtPath:@"MyFiles"
error:nil];
I then try to compare on of the NSStrings in the array:
for(int i = 0; i < [dirContent count]; i++) {
if([dirContent objectAtIndex:i] == @"MyFile") // This will never be True
So my questions is, what would be the reason why these two NSString pointers would work so differently? I know I shouldn't use "==" but at the moment, but I'm just so curious why it works sometimes.
I noticed some difference between them debugging. In the first case, the "newcategory"s "name" said (__NSCFConstantString*) and had the value visible. For some reason, the "dirContent" arrays contains two (__NSString*) objects where the values aren't visible.
This raises another question. What makes the NSString in the first case to become a constant? It seems to have something to with how it's created when I pass it to the function. When I allocate a new object with a NSString property that I then pass in to a function, the function sees it a constant(The NSString property of the object). But when the object is stored in a list and I grab it by passing [array objectAtIndex:index] into a function, the functions doesn't get it as a constant (the NSString property of the object that is).
Thanks!
回答1:
It may work, when the pointers point to the same object.
If you have a string literal in your code, it is actually a statically allocated object of type NSString
. At any point in your code, if you would reference this string value, you are actually using the same pointer. (A pointer is basically a memory address)
If you have the string literal @"abc"
at more than one point in your code, the compiler only puts in one instance, and uses a pointer to this single instance.
This explains why @"abc" == @"abc"
.
Taking your example:
if(newcategory.name != @"All")
will only work if at some point in your code you did:
newcategory.name = @"All";
And will not work if you would do:
newcategory.name = [NSString stringWithFormat:@"%c%c%c",'A','l','l'];
because in that last case you explicitly allocate a new string.
edit just tested, this example was flawed:
newcategory.name = [NSString stringWithString:@"All"];
because this is optimized away so you will have the same pointer to @"All"
回答2:
NString ALWAYS works with the "==" sign, if you want to compare two pointers to see if they reference the EXACT SAME object.
And short literals are generally pooled in such a way that likely @"ABC" == @"ABC", even if one of those literals is in a different class.
But don't count on it.
回答3:
When you compare with ==
you aren't comparing the strings themselves, you are comparing the values of the pointers to the strings. When you declare string literals in your code they are stored in the data segment of your executable. If more than one string variable is pointing to the same string literal, they may be pointing to the same memory location.
When you load the string from a file, the pointers cannot be equal since they couldn't have possibly come from the data segment of the executable.
For example, the two string literals asdf
will often only be stored once in the executable, thus the values of the pointers will be equal. This is an optimization performed by the compiler though and will not always work.
NSString* someVariable = @"asdf";
if(someVariable == @"asdf")
NSLog(@"They are equal!");
来源:https://stackoverflow.com/questions/9154288/why-does-nsstring-sometimes-work-with-the-equal-sign