I have next code:
// create new delegate
MyCustomApplicationDelegate *redelegate = [[MyCustomApplicationDelegate alloc] init];
redelegate.delegate = [(NSObject<UIApplicationDelegate42> *)[UIApplication sharedApplication].delegate retain];
// replace delegate
[UIApplication sharedApplication].delegate = redelegate;
...
[UIApplication sharedApplication].delegate = redelegate.delegate;
[redelegate.delegate release];
after last line the system called dealloc method of base UIApplicationDelegate class.
So, why? I read Apple documentation about UIApplication, about delegate property:
@property(nonatomic, assign) id delegate
Discussion The delegate must adopt the UIApplicationDelegate formal
protocol. UIApplication assigns and does not retain the delegate.
It clearly says that UIApplication assigns and does not retain the delegate. So, why it destroy my base delegate?
UIApplication has some unusual behavior. The first time that you set the delegate property on UIApplication, the old delegate is released. Every time after that, when you set the delegate property the old delegate is not released.
The declaration for the delegate property in UIApplication.h is:
This implies that the shared UIApplication will never call retain or release on the delegate. This is normal for the delegate pattern: A class normally doesn’t retain its delegate because this results in a retain loop.
But in this case, there’s an unusual problem: Who owns the app’s first delegate? In main.m the call to
UIAplicationMain()implicitly allocs and inits the first delegate, which leaves that delegate with a retain count of 1. Someone has to release that but there’s no classes around to own it. To solve this, whenever you set a new delegate on UIApplication for the first time, it releases that first delegate. The new delegate was alloced and initted by some class in your app, so you already own a reference to the new delegate. UIApplication doesn’t retain or release the new delegate.