Reputation: 18346
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?
Upvotes: 3
Views: 651
Reputation: 2521
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:
@property(nonatomic,assign) id<UIApplicationDelegate> delegate;
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.
Upvotes: 7
Reputation: 18346
I have an idea that old delegate after this:
[UIApplication sharedApplication].delegate = redelegate.delegate;
will be released.
But when i see this
@property(nonatomic, assign) id<UIApplicationDelegate> delegate
i'm thinking that it should not (because assign)
Do you agree with me?
Upvotes: 0
Reputation: 2722
I don't think you're supposed to change the UIApplication sharedApplication delegate like this. The standard delegate of your App is automatically the [UIApplication sharedApplication] delegate. So perhaps you should just put all your custom code in the normal delegate?
Upvotes: 0