Seify
Seify

Reputation: 310

dealloc call order

I have custom hierarchy of views. Each view retains its children. Nobody else but parent retains view. When dealloc for view is called, it calls [children release]. When I want to destroy a view and delete related resources, I call:

[mainView release];
[resourceManager deleteRelatedResources];

Most of the time it works well and the order of calls is:

  1. mainView dealloc;
  2. mainView's children's dealloc;
  3. mainView's grandchildren's dealloc etc.
  4. deleteRelatedResources

But sometimes (about 1% of times) I have another order:

  1. mainView dealloc;
  2. deleteRelatedResources
  3. mainView's children's dealloc;
  4. mainView's grandchildren's dealloc etc.;

I've found recommendation from Apple not to rely on dealloc' call for resource management. Is it true that dealloc of children's views could be called not right after [children release]? Are there any workarounds? (My project's gone too far to change Resource Management scheme).

Upvotes: 0

Views: 201

Answers (2)

scottrick
scottrick

Reputation: 110

My guess is that some of mainView's child views are being retained elsewhere for some reason (animation, or for some other use) so they aren't getting dealloc'd immediately.

You could test this by checking the retainCount of the view's children when its being dealloc'd.

Upvotes: 0

bbum
bbum

Reputation: 162722

The order of dealloc invocation is indeterminate; if you have code that has order dependences in the implementations of dealloc between different classes, consider that code broken.

Certainly, there are workarounds in that you can go to great lengths to try and guarantee order. But no workaround is bullet proof and you'll just be digging the hole deeper.

The only thing you can assume is that an object released in A's dealloc will always be deallocated after A. When? You can't definitively know.

(One issue is that any object is free to be retain/autoreleased at any time.)

One potentially quick fix is to add an invalidate pattern. That is, move resource management out of dealloc by implementing a method across all the classes with dependent resource management where you control the invocation of said method.

You then do something like:

[myObject invalidateAllResources]; // traverses object graph, in order, invalidating resources

[myObject release]; // do the normal release-maybe-dealloc dance

Upvotes: 4

Related Questions