BNRItems will not dealloc


#1

I wonder am I the only one who has trouble with the dealloc exercise in Chapter 3.

When I set the array ‘items’ to nil, the array gets destroyed but it seems that the contents (the BNRItems) do not and the BNRItem delloc method is not called.

Some experimentation shows that the problem seems to be related to the BNRItems being alloc-ed in the RandomItem Class method rather than in main().

If I create and alloc a BNRItem in main() it gets destroyed when the pointer is set to nil as you would expect but something seems to be retaining those objects alloc-ed in RandomItem.

By the way when the program terminates all the objects get destroyed and dealloc is called for all the BNRItems. I presume this is ARC tidying up when main is terminated but I can’t understand why setting items to nil doesn’t cause them to be destroyed. Surely items is the only owner?


#2

The other owner of the item is ‘newItem’ in randomItem. Since it is a return value, it seems supposed to be autoreleased after used in caller. If you put breakpoints around ‘}’ of autoreleasepool, you will notice that the item is destroyed after getting out the pool and before returning of main function.


#3

Yes. I believe you are right and that is why I see a string of deallocs at the end of the program but not at the point where the items array is set to nil.
I did some other tests on classes of my own and replicated the same behaviour.

But two points come to mind:

First, this seems to be an error in the book - or at least it could be a lot clearer. The text implies that the line

will trigger a chain reaction of deallocs but this is not quite the case. And the text doesn’t mention the autorelease pool at all so the more curious reader is baffled - as I was.

Second, isn’t this a kind of a memory leak? Far be it from me to question the magical powers of ARC but what if ‘items’ was a huge array with thousands of objects. If I dump items, I would expect all that memory on the heap to be freed up immediately . But it looks like all the objects will hang around unit the end of the release pool - which may not be until the end of main(). Is this something that the programmer should be conscious of?

Anyway, thanks for your clarification.


#4

If I remember correctly, there is an autorelease pool in run loop in iOS program, and the pool is drained in every loop like after processing touch event, cleaning up all objects used. However, as you concern, for advanced programs we might need tools like memory analyzer to find memory issues and need some way to handle it properly.