Custom dealloc and ARC (Objective-C)
When using ARC, you simply do not call [super dealloc]
explicitly - the compiler handles it for you (as described in the Clang LLVM ARC document, chapter 7.1.2):
- (void) dealloc
{
[observer unregisterObject:self];
// [super dealloc]; //(provided by the compiler)
}
Related videos on Youtube
Niku
Updated on July 18, 2022Comments
-
Niku almost 2 years
In my little iPad app I have a "switch language" function that uses an observer. Every view controller registers itself with my observer during its
viewDidLoad:
.- (void)viewDidLoad { [super viewDidLoad]; [observer registerObject:self]; }
When the user hits the "change language" button, the new language is stored in my model and the observer is notified and calls an
updateUi:
selector on its registered objects.This works very well, except for when I have view controllers in a TabBarController. This is because when the tab bar loads, it fetches the tab icons from its child controllers without initializing the views, so
viewDidLoad:
isn't called, so those view controllers don't receive language change notifications. Because of this, I moved myregisterObject:
calls into theinit
method.Back when I used
viewDidLoad:
to register with my observer, I usedviewDidUnload:
to unregister. Since I'm now registering ininit
, it makes a lot of sense to unregister indealloc
.But here is my problem. When I write:
- (void) dealloc { [observer unregisterObject:self]; [super dealloc]; }
I get this error:
ARC forbids explicit message send of 'dealloc'
Since I need to call
[super dealloc]
to ensure superclasses clean up properly, but ARC forbids that, I'm now stuck. Is there another way to get informed when my object is dying?-
Błażej Czapp over 11 yearsAs a side note - situation like this can cause a memory leak, which would not show in the Leaks tool. If the dataModel retains the reference to the observer (which is the default thing under ARC, even for ivars), the dealloc will never get called, as the retain count will be larger than zero. So, you may have to manually unregister the observer to enable the dealloc to be called in the first place.
-
Doug Watkins over 9 yearsI implemented something similar for right and left handed options. The only VC that needs the message is the currently displayed one. Others look at the model in viewDidLoad or viewDidAppear to make changes to the interface. Maybe something like this would work better.
-
Objectif over 7 years@BlazejCzapp since he is using a UITabBarController, and let's say the UITabBarController will always hold a reference to the registered controller (as I guess is the case with its 'child' controllers), will the memory leak still be an issue? I don't see when will the registered controller be allocated. Thanks
-
-
user443854 about 9 yearsIf view holds a reference to observer, and observer holds reference to the view, then we have a circular reference. So the view's reference count is greater than 0, and
dealloc
is never called. Does it make sense to call[observer unregisterObject:self]
in dealloc? What am I missing? -
hasan almost 8 yearsthats want work. cause the observer itself holds a reference to the controller. that will preventing the dealloc of getting called in the first place