2

Some sites are saying that this:

@property (nonatomic, strong) MyObject *foo;

self.foo = [[MyObject alloc] init];

increases the retain count to 2

but since the latest xcode version or ARC, this shouldnt be a problem right?

according to the video we can take out all autorelease

so from this:

@property (nonatomic, strong) MyObject *foo;

self.foo = [[[MyObject alloc] init] autorelease];

turns into this

@property (nonatomic, strong) MyObject *foo;

self.foo = [[MyObject alloc] init];

So should I ignore the website that says that self.foo = [[MyObject alloc] init]; increases retain count to 2?

dsgriffin
  • 66,495
  • 17
  • 137
  • 137
Ben
  • 565
  • 1
  • 3
  • 11

2 Answers2

3

Without ARC, you probably should be using retain (and correspondingly assign) rather than strong (and weak). In your first example, without ARC, the - init method returns an object with a retain count of 1, and the setter for the foo property increments the retain count to 2.

In your second example (which must be without ARC, since autorelease isn't available with ARC), the - autorelease call adds the object to an autorelease pool and reduces its retain count by 1, so the object ends up with a retain count of 1 (for the property).

With ARC, as in your third example, you don't need to worry about retain counts at all—that's the point of ARC. Under the hood, - init should still be returning an object with retain count 1 and the setter for foo should still be incrementing the retain count, but the compiler should be inserting a - release somewhere after the setter is called. Basically, with ARC, because the property is strong, you can rely on the object continuing to exist once you've assigned it to the property, and you don't have to think about retain/release/autorelease.

Isaac
  • 10,668
  • 5
  • 59
  • 68
  • so are you saying that using arc, @property (nonatomic, strong) MyObject *foo; self.foo = [[MyObject alloc] init]; will increment the retain count 2 but will eventually make the retain count 0? – Ben Mar 23 '13 at 00:09
  • 1
    First, the big point: if you're using ARC, you shouldn't think about retain counts at all; a strong property will ensure that whatever it's pointing to continues to exist. What I expect the implementation to be (though I have not checked the compiled output to verify) is that the object has a retain count of 1 after the init call but before being assigned to the property, a retain count of 2 after being assigned to the property, and then the compiler inserts a release statement to decrement the retain count back to 1—at this point, the property should be the only thing retaining the object. – Isaac Mar 23 '13 at 00:14
  • 1
    @Ben What it means is the compiler determines the lifetime of that object and inserts the necessary calls to `retain`, `release`, and `autorelease`. But it is a good idea to understand how memory mangement works, like you are. This answer has some good background: http://stackoverflow.com/a/6418410/620197 – Mike D Mar 23 '13 at 00:14
1

ARC makes that statement untrue. The autorelease isn't gone, it's just inserted by the compiler now and you can't see it.

Catfish_Man
  • 41,261
  • 11
  • 67
  • 84
  • Is the compiler inserting an `autorelease` or an actual `release` in the correct place? – Isaac Mar 22 '13 at 23:51
  • @Isaac That's an implementation detail. What does it matter? All that we care about is that the compiler isn't leaking memory unnecessarily. – CodaFi Mar 22 '13 at 23:57
  • @CodaFi: For the most part, yes, but it's worth knowing if autorelease pools are being used because there are cases where, for performance reasons, one would specifically use alternate autorelease pools and/or drain the pools at particular points. Also, it can change when the object goes away. – Isaac Mar 22 '13 at 23:58
  • @Isaac The point of storage qualifiers are to obviate the need to worry about most of that. Memory management and the performance thereof is now the job of the compiler, and we have very little say in how it works (short of going back to MRC). – CodaFi Mar 23 '13 at 00:01
  • @CodaFi: In general, I agree; it is, however, useful to know for debugging purposes, if the compiler is inserting a `release` immediately after what it thinks is the last use of a variable (as opposed to an `autorelease`), if the object that variable points to should continue to exist for the rest of a code block, but is mysteriously being deallocated. – Isaac Mar 23 '13 at 00:03