1

The following code is a snippet I took from a lecture on objective-c which is meant to illustrate the differences between identity and equality in objective-c.

There are a few things I don't understand about it and since one part of the code relates to the other, I have copied the code in full.

The first part:

// test for object identity:
NSString *a = @“Peter”;
NSString *b = @“Peter";
BOOL identical = a == b;  //YES

I don't understand how the objective-c compiler concludes that object a is identical to object b. I realise that they both contain the exact same string, namely "Peter", but I would have thought that since a and b are separate objects, that they would each have unique memory addresses as such, and I would have thought that the = operator then would be testing that rather than testing if a and b contain the same string.

Part 2:

// test for string equality: will return YES
NSString *aName = @"Peter";
NSMutableString *anotherName =
  [NSMutableString stringWithString:@"P"];

 [anotherName appendString:@"eter"];

BOOL equal = [aName isEqualToString:anotherName]; //YES 
BOOL identical = (aName == anotherName); //NO

I understand this code to have first created an object aName which is "Peter" and anotherName which is "P".

The next bit I don't get. My first problem understanding this: "eter" is appended to anotherName in a standalone statement before we test for equality but as far as I understand it, even though we say

[anotherName appendString:@"eter"];

we have not stored this result anywhere so that when we ask if anotherName is equal to the string in aName, I would have thought that anotherName was still just "P". And my second problem understanding this part 2 of the code, is that I don't see how they are equal. (Similar to my problem in Part 1.)

And again I do not know why the last line of code which tests for identity would return NO for not equal.

hinterbu
  • 747
  • 2
  • 7
  • 12
  • 1
    "I don't understand how the objective-c compiler concludes that object a is identical to object b" Because you've made a terrible mistake: you're using strings as your examples. Don't use strings, because they have special storage rules. Make your own object class, say Person, and do your testing with that. You will then understand. – matt Jul 09 '16 at 15:48
  • Based on your part 2 code -- aName will equal "Peter", anotherName will equal "P", the new strings are not equal, so equal is NO, and they are stored at different memory locations so identical will be no. – pds Jul 09 '16 at 16:02
  • Based on your part 1 of code -- The OS uses special rules (when it can) for NSStrings and NSNumbers that are identical. So, the OS has deemed the strings are the same and they will only store one copy of them. – pds Jul 09 '16 at 16:10
  • @pds sorry I accidentally deleted this line of code from Part 2: [anotherName appendString:@"eter"]; I have edited it now. Would you mind looking at it again? – hinterbu Jul 09 '16 at 16:57
  • Thanks all - is it the case then that the reason aName and anotherName are not deemed "identical" because they were not both created as @ string constants (aName was but anotherName wasn't)? – hinterbu Jul 09 '16 at 17:02
  • I'd venture a guess that almost everyone who looks into this gets tripped up by literal NSString interning. – jscs Jul 09 '16 at 17:21
  • "is it the case then that the reason aName and anotherName are not deemed "identical" because they were not both created as @ string constants" Yes, although even that is not guaranteed. For example, `NSString * name = @"Peter"; NSString * otherName = [NSString stringWithString:name]; BOOL equal = (otherName == name);` Also, even worse: `@"Hello, world" == [@"Hello, world" copy]` – jscs Jul 09 '16 at 17:26

1 Answers1

1

Your assumption is wrong. Objective-C doesn't guarantee to use different objects for identical data. Quite the opposite, the same object is used whenever possible. For example there are only two [NSNumber numberWithBool] objects, only one empty array object, only one [NSNull null] object etc.

In 64 bit code, all NSNumber objects with reasonable sized equal integers are the same objects. All NSString objects with small equal strings are the same object etc. The copy method returns the same object if the object is immutable.

gnasher729
  • 51,477
  • 5
  • 75
  • 98