Can someone refresh my memory? Question about NSString

Discussion in 'iOS Programming' started by chrono1081, May 8, 2013.

  1. chrono1081 macrumors 604

    chrono1081

    Joined:
    Jan 26, 2008
    Location:
    Isla Nublar
    #1
    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:
     
  2. ChristianJapan macrumors 68040

    ChristianJapan

    Joined:
    May 10, 2010
    Location:
    日本
    #2
    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 ...
     
  3. Duncan C, May 8, 2013
    Last edited: May 8, 2013

    Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #3

    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."};
    
     
  4. chrono1081 thread starter macrumors 604

    chrono1081

    Joined:
    Jan 26, 2008
    Location:
    Isla Nublar
  5. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #5
    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.
     
  6. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #6
    @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.

    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.
     
  7. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #7
    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.

    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.

    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.
     
  8. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #8
    No, it's the same.

    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.
     
  9. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #9
    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?
     
  10. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #10
    That's my understanding, yes.
     

Share This Page