8

When I alloc and init two NSString variables and compare their pointers, they are the same. Here's a snippet that shows this:

NSString *s1 = [[NSString alloc] initWithString:@"hello world"];
NSString *s2 = [[NSString alloc] initWithString:@"hello world"];

if (s1 == s2) {
    NSLog(@"==");
}else {
    NSLog(@"!=");
}

Why are s1 and s2 the same?

jscs
  • 63,694
  • 13
  • 151
  • 195
chancyWu
  • 14,073
  • 11
  • 62
  • 81
  • possible duplicate of [Difference between NSString literals](http://stackoverflow.com/questions/8032375/difference-between-nsstring-literals) – jscs Jul 23 '12 at 02:58
  • In your if statement, you are not comparing the pointers, but the data they point to, and looking at the code, I'd say "hello world" is 100% equal to "hello world". – David Skrundz Jul 23 '12 at 03:17
  • 2
    @NSArray: No, that's pointer comparison. You need to send a message (`isEqual:` or `isEqualToString:`) to compare the values. – jscs Jul 23 '12 at 03:18
  • @NSArray He _is_ comparing pointers. Comparing objects would entail using "*s1 == *s2" (which has no meaning for strings - you can't overload == in Objective-C). String contents are compared with `-isEqualToString:`, as pointed by @Josh. It will return `YES` provided the contents match, even if you are comparing two different instances. – Nicolas Miari Jul 23 '12 at 05:38

2 Answers2

14

There are three things going on here:

Firstly, the two identical string literals you're passing in to initWithString: will have the same address to start. This is an obvious optimization for constant data.

Secondly, when you nest alloc and init with strings, the runtime performs an optimization, the alloc call essentially becomes a no-op. This is done using the NSPlaceholderString class. This means the pointer you get back here will be coming from initWithString:, not from alloc.

Thirdly, under the hood, initWithString: is calling CFStringCreateCopy, which as you may find, has the following behavior: Since this routine is for creating immutable strings, it has an optimization. It simply calls CFRetain() and returns the same object that was passed in.

Thanks for the very interesting question. I had fun figuring it out.

Ken Aspeslagh
  • 11,484
  • 2
  • 36
  • 42
0

@"hello world" strings are of class NSConstantString.if you use @"hello world" in two places, they will be referencing the very same object.

From documentation.

The simplest way to create a string object in source code is to use the Objective-C @"..." construct:

NSString *temp = @"/tmp/scratch"; Note that, when creating a string constant in this fashion, you should use UTF-8 characters. Such an object is created at compile time and exists throughout your program’s execution. The compiler makes such object constants unique on a per-module basis, and they’re never deallocated, though you can retain and release them as you do any other object. You can also send messages directly to a string constant as you do any other string:

BOOL same = [@"comparison" isEqualToString:myString];

Parag Bafna
  • 22,812
  • 8
  • 71
  • 144