Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

chrono1081

macrumors G3
Original poster
Jan 26, 2008
8,924
6,642
Isla Nublar
Hi guys,

Its been at least a year since I touched code and I'm a bit rusty, can someone answer two questions for me? (Also this is just practice I know this won't compile because of the same variable names).

I have two lines of code here that simply assign a value to the NSString variable:

Code:
NSString *adam = @"Adam"; //Is this legal?
NSString *adam = [[NSString alloc] initWithFormat: @"Adam"]; //Is this the correct way?

I typed the first one by accident and didn't expect it to compile but it did. How come I didn't have to initialize this string?

Also regarding the second one, for simply assigning a value to a string I thought there was a different way instead of using [NSString alloc] initWithFormat] but nothing in the documentation jumped out at me as something I remembered doing.

Sorry if these sound silly its been awhile :eek:
 
For me also a while ... but I think to remember that the second version is safer because you could release.

If you try to release the first case you might run into an exception; specially in case of autorelease pools; now in days of ARC that might be wrong.

Again: I also didnt touch XCode for quite some time now.

Happy to get corrected ...
 
Hi guys,

Its been at least a year since I touched code and I'm a bit rusty, can someone answer two questions for me? (Also this is just practice I know this won't compile because of the same variable names).

I have two lines of code here that simply assign a value to the NSString variable:

Code:
NSString *adam = @"Adam"; //Is this legal?
NSString *adam = [[NSString alloc] initWithFormat: @"Adam"]; //Is this the correct way?

I typed the first one by accident and didn't expect it to compile but it did. How come I didn't have to initialize this string?

Also regarding the second one, for simply assigning a value to a string I thought there was a different way instead of using [NSString alloc] initWithFormat] but nothing in the documentation jumped out at me as something I remembered doing.

Sorry if these sound silly its been awhile :eek:


The first form is in fact legal, and is the recommended way to create static string objects.

The objective C language treats code like
Code:
@"some_text"
as a special case to create a statically allocated, immutable string object.

If you wanted to create a mutable string you could use code like this:

Code:
    NSMutableString *aString = [NSMutableString stringWithString: @"Foo"];
Using stringWithFormat is wasteful unless you actually need to build a string that combines different parts using a format string. It does a lot of extra work, and in fact, the call


Code:
NSString *adam = [[NSString alloc] initWithFormat: @"Adam"]; //Is this the correct way?

Creates the static NSString @"Adam" and passes it into the initWithFormat method, which then creates a second string object and hands it back to you.

BTW, the Objective C language was recently extended to allow you to create arrays, dictionaries, NSNumber objects, and a few others the same way. The following code is now legal:

Code:
NSNumber *aNumber = @6;
NSArray *anArray = @[@"one", @"two", @"three"];
NSArray *anArray = @[@1, @(1+1), @3];

NSDictionary *aDictionary = 
   @{@"name" :   @"Fred",
       @"Age":       @25,
       @"Address": @"123 Elm st."};
 
Last edited:
For me also a while ... but I think to remember that the second version is safer because you could release.

If you try to release the first case you might run into an exception; specially in case of autorelease pools; now in days of ARC that might be wrong.

Again: I also didnt touch XCode for quite some time now.

Happy to get corrected ...

No. There is no reason to release statically allocated strings. In non-arc, it doesn't do any harm, but doesn't do any good either.

In ARC, release is not needed (and not allowed)

In all cases, the original poster's second form (stringWithFormat) is wasteful and inefficient.
 
@Duncan,

Creates the static NSString @"Adam" and passes it into the initWithFormat method, which then creates a second string object and hands it back to you.
Can you prove this statement? It's probably not correct. Most likely the result is that the address of the string literal is returned. The guys that wrote foundation are sneaky that way, although stringWithFormat might screw this up.

BTW, the Objective C language was recently extended to allow you to create arrays, dictionaries, NSNumber objects, and a few others the same way.

Not really true. The new literal syntax is a shorthand for the similar alloc/init calls that create these objects. The string literal syntax doesn't create a new string. The string is created by the linker (or possibly the dynamic linker). The new literal syntax for containers is less efficient than the existing literal syntax for strings. It's possible that this could change in the future but I haven't read any comments regarding that. The new syntax is meant to be more convenient, terser, and more readable, but it's not necessarily more efficient.
 
@Duncan,


Can you prove this statement? It's probably not correct. Most likely the result is that the address of the string literal is returned. The guys that wrote foundation are sneaky that way, although stringWithFormat might screw this up.

StringWithFormat and initWithFormat run string parsing on the format string that's passed to them, looking for things like %@, %c, %f, etc, and using varargs to pull out additional parameters that are passed in. They then allocate a new string object using the results of the format string parsing.

Sure I can prove it. Take this code:

Code:
  NSString *fooString = @"foo";
  NSLog(@"fooString =   %08X", (unsigned int) fooString);
  NSString *newFooString = [[NSString alloc]initWithFormat: fooString];
  NSLog(@"newFooString =  %08X", (unsigned int) newFooString);

The result is this:

Code:
fooString =   000039D0
newFooString =  00121140

The objects are different.

Not really true. The new literal syntax is a shorthand for the similar alloc/init calls that create these objects. The string literal syntax doesn't create a new string. The string is created by the linker (or possibly the dynamic linker).

Understood. I was keeping it simple for somebody who's just learning the language. You'll notice that I said in my previous post that string literals were a shorthand.

The new literal syntax for containers is less efficient than the existing literal syntax for strings. It's possible that this could change in the future but I haven't read any comments regarding that. The new syntax is meant to be more convenient, terser, and more readable, but it's not necessarily more efficient.

Ok, now's its my turn. Can you prove that the new object literal syntax is less efficient than using arrayWithObjects, dictionaryWithObjectsAndKeys, etc?

It doesn't make any sense to compare the efficiency of creating an array vs creating a static string object. That's like comparing to see if it's hotter in the summer or in the city.
 
Ok, now's its my turn. Can you prove that the new object literal syntax is less efficient than using arrayWithObjects, dictionaryWithObjectsAndKeys, etc?

No, it's the same.

It doesn't make any sense to compare the efficiency of creating an array vs creating a static string object. That's like comparing to see if it's hotter in the summer or in the city.

It's more efficient to use a string literal than a string built with stringWithFormat. One might think that using the array literal syntax is also more efficient than building the same array using arrayWithObjects. But it's not.
 
The new object literal syntax is just "sugar" for the compiler, right?, similar to how Objective-C 2.0 added dot-notation but it just ends up as a message-send anyways?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.