UIApplication委托弱引用导致它为零?

时间:2014-07-29 23:04:20

标签: ios objective-c automatic-ref-counting uiapplicationdelegate

从以下实例化UIApplicationDelegate时:

UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]))

即使[[UIApplication sharedApplication] delegate]属性是弱引用,AppDelegate仍保留在内存中。

但是,如果您取消设置并重新设置委托属性,请执行以下操作:

id originalDelegate = [[UIApplication sharedApplication] delegate];
[[UIApplication sharedApplication] setDelegate:nil];
[[UIApplication sharedApplication] setDelegate:originalDelegate];

然后它变得无效使用。知道为什么最初的弱引用很好吗?

3 个答案:

答案 0 :(得分:1)

当指向它的指针设置为nil时,它会与应用程序的窗口一起被释放。保持一个强大的指针,它会留在...

@property(strong, nonatomic) AppDelegate *strongAppDelegate;

self.strongAppDelegate = [[UIApplication sharedApplication] delegate];
[[UIApplication sharedApplication] setDelegate:nil];
[[UIApplication sharedApplication] setDelegate:self.strongAppDelegate];

这可以通过在AppDelegate和NSLogging中实现dealloc来证明。

编辑 - 无论如何,阅读您打算如何使用它,请考虑两种选择:

  1. 向您的api添加方法,以便从客户端的app委托中调用 钩
  2. (甚至更好)订阅UIApplication的状态更改 通过NSNotificationCenter(例如“通知”下的see the doc。它发布了类似的内容 UIApplicationDidBecomeActiveNotification)。
  3. 介入客户的应用程序和代理挂钩(即使只是片刻)似乎是一种大多数人不喜欢的妥协。

答案 1 :(得分:0)

当然,实现是不透明的,可能会在未来发生变化,但似乎框架在发布时对retain进行额外调用,之后通过发送{{1}来平衡在release中。您可能必须将原始委托实例存储在某个属性中。我想如果您想对潜在的泄漏事项要格外小心,可以尝试使用KVO来观察应用程序对象的setDelegate:属性的更改,以便您可以对额外属性进行相应的更改。

但它可能仍然有点冒险,因为我们不知道幕后还会有什么影响。 (例如,app委托可能需要注册才能接收某些通知等)。这很不幸,因为在运行时切换app委托实例在我看来并不是一件不合理的事情。

修改

如果可能的话,看看你是否可以通过注册delegate实例发布的一些通知来完成所需的工作 - 它们非常全面。不幸的是,您一直在探索的方法风险很大。

答案 2 :(得分:-2)

id originalDelegate = [[UIApplication sharedApplication] delegate]; //weak reference point to delegate. delegate is a weak property
[[UIApplication sharedApplication] setDelegate:nil]; // delegate point to nil, originalDelegate was pointing to delegate so now originalDelegate points to nil as well.
[[UIApplication sharedApplication] setDelegate:originalDelegate]; // delegate points to originalDelegate which was pointing already to nil.