2

Obviously I'm not just referring to NSString; there is [NSDictionary dictionary], [NSArray array], and so on. But why have all these methods when we can just send [NSDictionary new], [NSArray new], etc.?

Léo Natan
  • 56,823
  • 9
  • 150
  • 195
PopKernel
  • 4,110
  • 5
  • 29
  • 51
  • Very closely related: [With ARC, what's better: `alloc` or autorelease initializers?](http://stackoverflow.com/q/6776537) – jscs Feb 17 '14 at 21:27

3 Answers3

6

The reason is primarily historical, because the distinction between the two is the reference count of the created object; caring about the reference count has been almost completely obviated by Automatic Reference Counting.

+string and methods like it return objects that are not owned by the caller (they are in an autorelease pool). +new, on the other hand, is one of the "four NARCs", and it does create owning references.

Previous to ARC, you would choose the one that had the memory management implications you needed in particular situation. Now, you can use whichever you prefer. There is no difference at the level of your code.

In some looping cases you may find it preferable to use +new because this still does apparently shorten the lifetime of the object as compared to +string.

Community
  • 1
  • 1
jscs
  • 63,694
  • 13
  • 151
  • 195
  • Actually, `new` is much preferred with ARC, because then one loses the need to `@autoreleasepool { ... }` when doing allocation heavy block of code. – Léo Natan Feb 17 '14 at 21:20
  • 1
    Are you certain that the constructors still put their results into a pool, @LeoNatan? `objc_retainAutoreleasedReturnValue()` is available to avoid that. – jscs Feb 17 '14 at 21:26
  • 1
    I thought so too, but no: http://stackoverflow.com/questions/21172044/lack-of-autorelease-optimization-under-arc-compiler – Léo Natan Feb 17 '14 at 21:28
3

To add upon Josh's good answer, when using ARC, using alloc] init] or new is preferred, because you lose the need for @autoreleasepool { ... } to relieve autorelease pressure.

Consider the following code:

for(int i = 0; i < X; i++)
{
    //@autoreleasepool {
    NSMutableArray* array = [NSMutableArray array];

    for(int j = 0; j < Y; j++)
    {
        [array addObject:[NSString stringWithFormat:@"%d", j]];
    }

    ///Do something with array.

    //}
}

As X and Y grow, you will find the memory growing, and would need @autoreleasepool because the objects would only be released when the autorelease pool is drained.

Now consider

for(int i = 0; i < X; i++)
{
    NSMutableArray* array = [NSMutableArray new];

    for(int j = 0; j < Y; j++)
    {
        [array addObject:[[NSString alloc] initWithFormat:@"%d", j]];
    }

    ///Do something with array.
}

Here the objects are released once they go out of scope and are no longer retained.

Léo Natan
  • 56,823
  • 9
  • 150
  • 195
2

Methods like [NSDictionary dictionary], [NSArray array] and so on, return autoreleased object. Meaning that you don't have the ownership of those objects, and you don't need to worry about memory management.
When you use new or alloc you need to release those objects once you have finished using them.

This distinction is important when you're not using ARC.

Merlevede
  • 8,140
  • 1
  • 24
  • 39