2
votes

At some point in my app I remove a view controller (let's call it A) from its parent view controller (let's call it B). And even though A is not referenced anymore, its dealloc method is not called.

I checked with instruments, A is really being freed. The number of living objects (of class A) is 0.

NSZombie is not enabled, I saw that it could interfere with dealloc calls.

The only moment the dealloc method is called, is when the view controller B is deallocated. At that moment, the stack trace is like that :

#0  0x0001ac78 in -[MyViewController dealloc] <-- This is A
#1  0x021061bf in _objc_deallocOnMainThreadHelper ()
#2  0x029f34d0 in _dispatch_client_callout ()
#3  0x029e1726 in _dispatch_main_queue_callback_4CF ()
#4  0x0274443e in __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ ()
#5  0x026855cb in __CFRunLoopRun ()
#6  0x026849d3 in CFRunLoopRunSpecific ()
#7  0x026847eb in CFRunLoopRunInMode ()
#8  0x046095ee in GSEventRunModal ()
#9  0x0460942b in GSEventRun ()
#10 0x00db4f9b in UIApplicationMain ()
#11 0x00028ea2 in main at /../main.m:17

I am not sure how the dealloc is triggered

Any idea what can be happening here?

-- EDIT

I create the view controller A with a class method :

+ (instancetype)viewController
{
    return [[MyViewController alloc] init];
}

The weird thing is that when I replace the call to this class method with [[MyViewController alloc] init] everything works as expected. I don't know what's happening. Any idea?

2
There is not enough information here and you call the classes "A" and "B" but which one is MyViewController? The stack trace is incomplete (skips from 1 to 10) - you need to zoom the window to open all of the entries. To the original question - How is A allocated and used? Show more code.Brian Walker
Do you have some logic you want to happen in dealloc or are you curious about how garbage collection works?brodney
@BrianWalker : This is the full stack trace I have in Xcode, there's nothing between 1 and 10. Or I don't know how to find it. I'll try to add more codeMartinMoizard
@brodney : ARC is not a garbage collector. And yes I need to perform some important actions in deallocMartinMoizard
I meant to ask whether you were depending on them happening at a certain time. You can see between 1-10 with the slider at the bottom of the stack trace panel.brodney

2 Answers

1
votes

I finally found what was going on.

The view controller that was not being dealloc was created through a class method, for example :
+ (instancetype) createMyViewController.

This kind of methods return autorelease objects.

My only guess is that the autorelease pool is drained way too late in my case. Adding an @autoreleasepool {} block around the appropriate code fixed everything.

0
votes

Check out these view controller lifecycle methods. One of them is probably the right place for the code you have in dealloc, and you can count on them being called at the times stated. Dealloc should only be used for memory cleanup, e.g. free.

- (void)viewWillDisappear:(BOOL)animated

- (void)viewDidDisappear:(BOOL)animated