2

When giving a NSString a value using = @"", what exactly is that shorthand for? I noticed that, all other things being equal in an application, global NSStrings made with @"" don't need retain to be used outside of the methods that gave them that value, whereas NSStrings given a value in any other way do.

I have found this question utterly unsearchable, so I thank you for your time.

  • http://clang.llvm.org/docs/ObjectiveCLiterals.html might help, they are generally called `Literal`s - NSStrings are a little bit special in the way that they were in the language from the beginning and I cannot think of a way to create a NSString without them other than from a char array. – luk2302 Dec 13 '15 at 20:01
  • Closely related: [Purpose of @ symbol before strings](http://stackoverflow.com/q/4446308) and [How ObjC handles the memory of immutable strings?](http://stackoverflow.com/q/11249591) (As an aside, DuckDuckGo will search for symbols.) – jscs Dec 13 '15 at 20:15
  • Thank you. @JoshCaswell Thank you for the tip with DuckDuckGo! – Archibald Platypus Dec 14 '15 at 03:00

3 Answers3

1

Objective-C is a super-set of C, which means you should be able to write C code in there and have it work. As a result, the compiler needs a way to distinguish between a C string (an old-school series of bytes) and an Objective-C NSString (Unicode support, etc). This is done using the @ symbol, such as @"Hello".

@"Hello" can't be released because it's a literal string – it's been written into the program when it was built, versus being assigned at run-time.

TwoStraws
  • 12,862
  • 3
  • 57
  • 71
1

A related answer: Difference between NSString literals

In short, when writing @"" in the global scope of your program, it does the same as writing "": The literal string you specified will be embedded in your binary at compile time, and can thus not be deallocated during runtime. This is why you don't need release or retain. The @ just tells the compiler to construct a NSString object from the C string literal. Mind you that this construction is very cheap and probably heavily optimized. You can follow the link and see this example:

NSString *str = @"My String";
NSLog(@"%@ (%p)", str, str);

NSString *str2 = [[NSString alloc] initWithString:@"My String"];
NSLog(@"%@ (%p)", str2, str2);

Producing this output:

2011-11-07 07:11:26.172 Craplet[5433:707] My String (0x100002268)
2011-11-07 07:11:26.174 Craplet[5433:707] My String (0x100002268)

Note the same memory addresses

EDIT: I made some test myself, see this code:

static NSString *str0 = @"My String";

int main(int argc, const char * argv[]) {
    NSLog(@"%@ (%p)", str0, str0);

    NSString *str = @"My String";
    NSLog(@"%@ (%p)", str, str);

    NSString *str2 = [[NSString alloc] initWithString:@"My String"];
    NSLog(@"%@ (%p)", str2, str2);

    return 0;
}

Will produce this output:

2015-12-13 21:20:00.771 Test[6064:1195176] My String (0x100001030)
2015-12-13 21:20:00.772 Test[6064:1195176] My String (0x100001030)
2015-12-13 21:20:00.772 Test[6064:1195176] My String (0x100001030)

Also, when using the debugger you can see that the actual object being created when using literals are in fact __NSCFConstantString objects. I think the related concept to that is called Class Clusters

enter image description here

Community
  • 1
  • 1
Patrick
  • 415
  • 5
  • 11
  • Note that having the same address is an artifact of the tooling and should not be depended upon. When comparing strings do not use address, use the `isEqual:` or `isEqualToString:` methods. See the "caveats" section here: http://clang.llvm.org/docs/ObjectiveCLiterals.html – quellish Dec 13 '15 at 20:17
1

String allocated using the literal syntax i.e @ reside as c strings in the data segment of the executable. They are allocated only once at the time of program launch and are never released until the program quits.

As an exercise you can try this:

NSString *str1 = @"Hello";
NSString *str2 = @"Hello";
NSLog("Memory Address of str1 : %p", str1);
NSLog("Memory Address of str2 : %p", str2);

both the log statements will print the same address which means literals are constant strings with lifetimes same as that of the program.

SayeedHussain
  • 1,696
  • 16
  • 23