Reconsidering +new

By: Jeremy W. Sherman. Published: . Categories: obj-c holy-wars.

Received wisdom teaches that Objective-C’s alloc-init two-step is important for both clarity and extensibility. And even if those two reasons don’t sway you, it’s both childish and déclassé to continue using +new past a certain programmer-age.

Or is it? Yes, creating a new object requires allocating its storage and then initializing it. But they’re not really distinct any more. It’s not like we do:

id obj = [Foo alloc];
if (!obj) error("allocation failed");
obj = [obj init];
if (!obj) error("init failed");

And zones are dead, so separating alloc and init so you can do:

id obj = [[Foo allocWithZone:fooZone] init];

doesn’t really matter any more, either.

And it breaks down even further when you look at Core Foundation analogs. There is no CFAlloc() followed by CFArrayInit(). Core Foundation just has Create methods that take an allocator to handle the “different zones” concern. Normally, you just pass NULL or kCFAllocatorDefault for the allocator argument, but either allocators have better support than zones at this time, or Apple just doesn’t care enough to write “don’t use allocators any more” anywhere.

Since these are equivalent:

CFMutableArrayRef array = CFArrayCreateMutable(
    NULL, 0, &kCFTypeArrayCallbacks);
NSMutableArray *array = [[NSMutableArray alloc] init];

I see no reason not to just do a “single call” alloc-init in Foundation-land, too:

NSMutableArray *array = [NSMutableArray new];

This for the common case. When you need to pass args in during construction, back to alloc-initWith… it is!

Aside: As a practical motivation for +new, when I’m throwing together a quick commandline program to see whether something behaves one way or another, [Blah new] types a lot faster than [[Blah alloc] init], particularly if I forget the double-bracket at the start and have to back up and fix it.

Aside 2: Many of the Foundation types let you get away with a compromise, like [NSMutableArray array]. In ARC-land, this is effectively no different than writing [NSMutableArray new] – what if you later need an arrayWithObjects:! what if you later need to allocate it in a different zone! –, but I never see anyone inveighing against -array, or -string, or -dictionary. So.