views:

1877

answers:

4

I've seen it claimed that the following are "pretty much equivalent":

foo([NSString stringWithString:@"blah"])                       # version 1
foo([[[NSString alloc] initWithString:@"blah"] autorelease])   # version 2

Are the above in fact literally equivalent or are there any subtle differences? What are reasons to prefer one or the other?

+8  A: 

They are equivalent, but I prefer "stringWithString" since it is more concise.

Martin Cote
+5  A: 

In most cases, the only difference is an extra call to objc_msgSend.

Decompiling NSString reveals that instead of sending +alloc it sends +allocWithZone:NSDefaultMallocZone()

rpetrich
Hmm, sounds like "not literally equivalent but different only in ways that all but the most hardcore obj-C hackers should not worry their pretty little heads over"? Still, it begs for the follow-up question: What's the difference between alloc and allocWithZone?
dreeves
Going by how other similar method pairs work, I'd guess that +alloc does exactly that - +allocWithZone:NSDefaultMallocZone().
Noah Witherspoon
It does indeed :)
rpetrich
There's really no need to worry about memory zones these days. IIRC, it used to be that memory zones could be used to gain some efficiency by grouping (and freeing) dependency chains as a zone, but nowadays it's mostly a relic.
Chuck
+5  A: 

The two are functionally equivalent, but as rpetrich observes, may operate ever-so-slightly differently internally. This shouldn't matter to you, use whichever seems more convenient to you. Furthermore, while there is a minute performance difference, it is highly unlikely to matter to your application in practice.

But all this misses a crucial point: both are pointless. By writing @"foo" you already have a fully functional NSString object. There is no need to mess around with extra methods to duplicate the string; it is quicker and simpler to just do:

foo(@"blah")
Mike Abdullah
Thanks mike! Good point about foo(@"blah") though I actually distilled that down from messier code where that wouldn't be possible.
dreeves
+4  A: 

Methods such as +stringWithString: or +array are simply convenience methods which always return autoreleased objects. These are mostly in place to reduce the amount of code written for classes that are created often, such as strings, arrays, dictionaries, numbers, etc. They strictly follow the basic memory management rules from which the one I mentioned above are derived.

this is then no.1 reason why they are different
Johannes Rudolph
since you made the autorelease yourself -> no difference
Johannes Rudolph