Home > Enterprise >  A developer when going through a code base encounters two different syntaxes for creating a NSString
A developer when going through a code base encounters two different syntaxes for creating a NSString

Time:11-13

1. NSString *str1 = [NSString stringWithInt: 10];

2. NSString *str2 = [[NSString alloc] initWithInt: 10];

What is the difference between these methods?

CodePudding user response:

The history goes to times when automatic reference counting doesn't existed. Then Apple have created notation, that methods with prefixes init, copy, new returns owned pointer, that mean that you don't need to retain it, other methods should return autoreleased pointers. For example

NSString *a;
NSString *b;

@autoreleasepool {
  a = [[NSString alloc] initWithFormat:@"%d", 1];
  b = [NSString stringWithFormat:@"%d", 2];

  NSLog(@"String a in autorelease pool is %@", a); //output: String a in autoreleasepool is 1
  NSLog(@"String b in autorelease pool is %@", b); //output: String b in autoreleasepool is 2

}

NSLog(@"String a out of autorelease pool is %@", a); //output: String a out of autorelease pool is 1
NSLog(@"String b in autorelease pool is %@", b); //crash: referencing invalid object, because b was autoreleased but variable `b` still pointing at released object

For proper working outside autoreleasepool variable b should be retained:

NSString *b;

@autoreleasepool {
  b = [[NSString stringWithFormat:@"%d", 2] retain];
  NSLog(@"String b in autorelease pool is %@", b); //output: String b in autoreleasepool is 2
}
NSLog(@"String b out of autorelease pool is %@", b); //output: String b out of autorelease pool is 1

But if you use retain properties, you will face opposite situation: memory leaks. Proper code will be

@property (retain) NSString *a;
@property (retain) NSString *b;

@autoreleaspool {
  self.a = [[[NSString alloc] initWithFormat:@"%d", 1] autorelease];
  self.b = [NSString stringWithFormat:@"%d", 2];
}

So exact implementation of stringWithFormat: is doing alloc init autorelease

Of course now when we have ARC we don't need think about proper object retaining and releasing. In ARC first code snipped will work fine without crashes, second code snippet will work fine without memory-leaks.

So now it's just for programmer sense which one he prefer most. It's like in swift: you can write: SomeClass(...) or SomeClass.init(...)

CodePudding user response:

The first is a class factory method. See http://www.apeth.com/iOSBook/ch04.html#_class_methods_2

The second is a genuine initializer.

The difference between them was much more obvious back in the day of manual memory management. Now that ARC exists, they are indistinguishable — which is why Swift eliminates the former.

  • Related