我有下一个代码:
// 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];
在最后一行之后,系统调用了基础UIApplicationDelegate类的dealloc方法。 所以为什么?我阅读了有关UIApplication的Apple文档,关于委托属性:
@property(nonatomic,assign)id delegate
讨论代表必须采用UIApplicationDelegate正式 协议。 UIApplication分配并不保留代表。
它清楚地表明UIApplication分配并且不保留代表。那么,为什么它会破坏我的基础代表?
答案 0 :(得分:5)
UIApplication有一些不寻常的行为。第一次在UIApplication上设置委托属性时,将释放旧委托。每次在此之后,当您设置委托属性时,旧委托不会被释放。
UIApplication.h中委托属性的声明是:
@property(nonatomic,assign) id<UIApplicationDelegate> delegate;
这意味着共享UIApplication永远不会在委托上调用retain或release。对于委托模式,这是正常的:类通常不保留其委托,因为这会导致保留循环。
但在这种情况下,有一个不寻常的问题:谁拥有该应用的第一个代表?在main.m中,对UIAplicationMain()
的调用隐式地分配并调用第一个委托,这使得该委托的保留计数为1.有人必须释放它,但是没有类可以拥有它。要解决这个问题,无论何时第一次在UIApplication上设置新委托,它都会释放第一个委托。新代理由应用程序中的某个类分配和启动,因此您已拥有对新代理的引用。 UIApplication不保留或释放新代表。
答案 1 :(得分:0)
我认为您不应该像这样更改UIApplication sharedApplication委托。您的应用程序的标准委托自动为[UIApplication sharedApplication]委托。那么也许您应该将所有自定义代码放在普通代理中?
答案 2 :(得分:0)
在此之后,我有一个老委员的想法:
[UIApplication sharedApplication].delegate = redelegate.delegate;
将被释放。
但是当我看到这个
时@property(nonatomic, assign) id<UIApplicationDelegate> delegate
我认为它不应该(因为指定)
你同意我的意见吗?