4

When we need create an object and take ownership of it we write

NSObject *someObject = [[NSObject alloc] init];

After that someObject's retain count will be equal to 1. Which method increases the count, alloc or init, and where in Apple's docs is this behavior described?

jscs
  • 63,694
  • 13
  • 151
  • 195
Rostyslav Druzhchenko
  • 3,673
  • 3
  • 33
  • 38

3 Answers3

12

After that someObject's retainCounter will be equal 1. Question is which method increases retainCounter alloc or init and there in Apple docs this behavior is described?

"Neither", "Both", or "One or the Other" would all be correct answers. A better answer would be "it is an implementation detail and you need to focus on the general, non implementation dependent rule".

First, ditch the notion of absolute retain counts. It is a useless way to think of this.

+alloc returns an object with a +1 retain count. Whatever is returned by +alloc must be -released somewhere. Wether or not the actual retain count is 1 or not is entirely an implementation detail and it often is not 1 for many of Apple's classes.

-init consumes the retain count of the messaged object and produces an object of retain count +1 (not 1, but "plus 1"); the result returned from init must be released to be managed correctly.

More often than not, init simply calls return self; without internally manipulating the retain count. This preserves the above rule.

Sometimes it doesn't, though, which is why you always have to have self = [super init] (checking the return value, of course) in your initializers and why you should never do something like Foo *f = [Foo alloc]; [f init];.

bbum
  • 162,346
  • 23
  • 271
  • 359
11

The alloc method does the actual allocation therefore will generally* increase the retain count. The init is responsible for initializing the object after the allocation.

*There are exceptions to this in several foundation classes as well as 3rd party code (class clusters for example) but you are always responsible for calling release/autorelease after a call to alloc in manual memory management

Joe
  • 56,979
  • 9
  • 128
  • 135
  • This simply isn't universally true. For example, `NSString`'s `alloc` method doesn't allocate anything. – bbum Apr 20 '12 at 22:13
  • No but in the case of `NSObject` and the custom subclasses a developer creates will generally follow this rule. `NSString` is often the exception to many memory management patterns. – Joe Apr 20 '12 at 22:17
  • Not just NSString, though -- many classes do not follow this general pattern (NSNumber, UIImage, a slew of others). Your answer reads like a definitive comment on the behavior of `alloc`. – bbum Apr 20 '12 at 22:19
  • @bbum I agree that it sounded like a definitive answer on `alloc` and `init` and I've updated. +1 to your answer as well. – Joe Apr 20 '12 at 22:25
5

Well, so it's kinda complicated. For almost all cases, +alloc increments the retain count, and -init does nothing to the retain count.

But occasionally, -init will want to return a pre-existing object rather than initializing the blank one alloc passed it. (NSNumber does this, for example.) In that case, -init would release self, then return a new object with a +1 retain count.

In the ARC documentation, they say that -init is a method which "consumes" its recipient, and returns a retained object. Often, that just means init does nothing to the retain count. But sometimes, -init is actually doing some retaining.

If this is confusing to you, don't worry about it.

As I said, +alloc is the one doing the retaining. -init is guaranteed to return a retained object, but doesn't itself do any retaining in most cases.

BJ Homer
  • 48,806
  • 11
  • 116
  • 129