0

I read that when using ARC in Objective-C programming in Xcode the dealloc method is called automatically by the compiler. Under what circumstances is it called?

In order to avoid having too many variable names, when I need to repeatedly use the same classes to do multiple operations (and resetting the variable each time) I often declare the variables, set them to nil, and then assign values to them as I go. This ends up looking like this:

MyClass mc;

mc = [[MyClass alloc] init];
[mc doThis:someOption]

mc = [[MyClass alloc] init];
[mc doThis:someOtherOption];

//etc...

The method name alloc is short for "allocate" because it is the method where memory is allocated to the variable. Does the compiler automatically release the memory for sc every time I assign it a new value? I plan on using this method in a project of mine, and I don't want a lot of memory being allocated with all the times I call alloc to assign a new value to mc.

Arc676
  • 4,445
  • 3
  • 28
  • 44

3 Answers3

5

The compiler never calls dealloc. The compiler inserts retain, release and autorelease (more efficient equivalents, really) as necessary to follow the memory management rules.

When the compiler inserts said calls is up to the compiler and the details will change across different compiler versions and different optimization levels.

I.e. you shouldn't need to worry about it in general.

However, autorelease pressure can still be an issue, as can retain cycles. Thus, you should definitely poke about your app with the Allocations Instrument to both measure the high-water mark and make sure your app isn't leaking memory over time.

bbum
  • 162,346
  • 23
  • 271
  • 359
  • Thanks for the tip. I checked out Instruments; is there a way to run my project in Instruments without exporting it? It seems that Instruments only records information for applications (.app), but my project isn't ready for that. – Arc676 Jan 14 '14 at 19:51
  • Why isn't there an optimization in the compiler, which would take ownership of the object in the inner-most scope, remove the object from the autorelease pool, and release it when the scope ends? For some time, I thought there was such an optimization, but alas, I was wrong. – Léo Natan Jan 16 '14 at 18:36
  • @LeoNatan removing an object from an autorelease pool costs basically the same as simply releasing it (with the appropriate retain in the first place). You may be thinking of the optimization that occurs when arc'd code calls a factory method on a class that returns an autoreleased object. At runtime, that code can effectively short circuit the autorelease entirely. – bbum Jan 16 '14 at 18:49
  • @bbum Yes, but object's release is delayed until the autorelease pool is drained, which in turn may required wrapping code with `@autoreleasepool` to prevent bloat. But why can't the compiler optimize this out? I formulated this into a question: http://stackoverflow.com/q/21172044/983912 – Léo Natan Jan 16 '14 at 20:24
  • @einsteinx2: Thanks for the help. With the allocations instrument I saw the memory usage. The actual memory used by the app is "live bytes" right? How do I forcibly release memory with ARC enabled? – Arc676 Jan 17 '14 at 21:18
  • Basically by making sure there are no string references to the object. That's for all intents and purposes the same as calling release (as ARC adds that for you). If you're inside a loop, use an autorelease pool to release dead objects each iteration. – Ben Baron Jan 17 '14 at 23:27
0

I read that when using ARC in Objective-C programming in Xcode the dealloc method is called automatically

In Objective-C, you never call -dealloc directly whether or not you're using ARC.

Under what circumstances is it called?

-dealloc is called when an object's retain count drops to zero. That is, it's called when all the objects that had previously asserted "ownership" of the object (by calling +alloc or -retain or -copy or +new) have renounced that ownership (by calling -release or -autorelease).

Does the compiler automatically release the memory for sc every time I assign it a new value?

If you're using ARC (and you should be), the compiler will insert appropriate calls to -retain, -release, etc. so that memory is managed appropriately. That said, you still need to understand how memory management works, and you should be familiar with the material in Advanced Memory Management Programming Guide.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • I thought that when you use ARC you don't call `release` or `autorealease` either. I need to know if the memory will be released even if `release` is never called. – Arc676 Jan 14 '14 at 18:47
  • 1
    Right -- with ARC you don't call `-release` or `-autorelease`. As I said above and bbum said even better, the compiler inserts those calls for you. – Caleb Jan 14 '14 at 18:51
0

Under ARC, your variable mc will hold a strong reference to only one instance of MyClass at a time, so when you allocate the second one and assign it to the variable, the first one should be getting deallocated, assuming your doThis: method doesn't do something that will create another strong reference to that instance, or that you're not doing anything else in your code that you've omitted that will keep a strong reference.

That being said, it would be a good idea for you to run your app with Instruments to see how much memory your app uses during this. Your instances shouldn't be getting autoreleased, so you shouldn't have to worry about them remaining around until the autorelease pool is drained, but I don't know what you might being doing when you init an instance of the class, or what you might be doing in your doThis: method, so if you're concerned, it's always a good idea to profile it with Instruments for memory allocations and leaks.

Gavin
  • 8,204
  • 3
  • 32
  • 42