【问题标题】:Does an iOS app's app delegate need to retain the UIWindow?iOS 应用的应用委托是否需要保留 UIWindow?
【发布时间】:2011-10-29 04:38:01
【问题描述】:

在诸如“基于视图的应用程序”之类的 iOS 应用程序的 Xcode 模板中,创建了一个 MainWindow nib,其中包含三个顶级对象:App Delegate、Window 和主 View Controller。 App Delegate 为窗口和视图控制器定义了retain 出口/访问器。我不明白为什么 App Delegate 需要保留这些对象,因为它们已经是 nib 中的顶级对象,因此应该由 UIApplication 保留。检查这些对象的retainCount 确实显示1 用于应用程序委托,2 用于窗口和视图控制器。我可以/应该将这些改为assign 吗?

我知道这是一件很挑剔的事情,但我希望理解这样做的原因能够提高我对 iOS 内存管理的整体理解。

【问题讨论】:

    标签: iphone ios memory-management


    【解决方案1】:

    似乎应用委托确实需要保留window UIWindow。

    新 Xcode 项目中应用程序委托的默认实现包括:

    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow?
    
    }
    

    如果您删除 window 属性并改用局部变量,应用程序将启动到黑色屏幕。

    Xcode 也会记录错误:

    [Application] 如果要使用主情节提要文件,应用委托必须实现 window 属性。

    The app delegate must implement the window property if it wants to use a main storyboard file swift


    将window 属性设置为weak 同样会启动黑屏。当您将 UIWindow 分配给属性时,Xcode 会显示错误:

    实例将立即被释放,因为属性“窗口”是“弱”

    【讨论】:

      【解决方案2】:

      在 iOS 中分配很棘手,我使用 @property(非原子,保留)。与 Mac OS 不同,iOS 中连接到 XIB 对象的出口不会自动保留和管理内存,这可能会随着 iOS 5 改变,但不太可能。

      这样做的理由是,您可以在 - (void)viewDidUnload 中释放任何视图对象,并删除您不需要的任何视图,或者可以在 -(void)viewWillAppear 上重新初始化。但表面上,目标是让您控制收集的内容和不收集的内容。

      我的模式是只为它们声明普通的可可访问器,就像我对任何其他属性一样,并在 viewDidUnload 中将它们设置为 nil

      - (void)viewDidUnload
      {
          [super viewDidUnload];
          self.buttonOne = nil;
          self.buttonTwo = nil;
          self.buttonThree = nil;
          self.buttonFour = nil;
          self.buttonFive = nil;
          self.buttonSix = nil;
          self.lineWidthSlider = nil;
          // Release any retained subviews of the main view.
          // e.g. self.myOutlet = nil;
      }
      

      您是对的,但是,保留窗口并没有多大意义,但恕我直言,这对于一致性是有意义的。这么啰嗦的说法是,根据我的经验,应用程序委托确实需要保留 UIWindow,否则它可以在内存扫描中收集并导致一些随机崩溃。

      【讨论】:

      • 但是 UIApplication 不保留笔尖中的所有顶级对象,包括窗口?如果是这样,那么除非 UIApplication 释放它(我认为这只会在退出应用程序时发生),否则该窗口将永远不会通过内存扫描被清理。
      • +1 保留顶部窗口也不需要任何成本,因为只要应用程序正在运行,它就永远不会被释放。
      • UIApplication 确实保留了应用程序的顶部窗口,但是当使用 VGA 时,您可能有多个窗口,因此如果您在使用它时需要 resignKeyWindow,我认为您将需要保留。来自苹果的文档“您可以通过编程方式或使用 Interface Builder 创建和配置应用程序的主窗口。在任何一种情况下,您都应在启动时创建窗口并应保留它并将对它的引用存储在您的应用程序委托对象中。” - developer.apple.com/library/ios/#documentation/WindowsViews/…
      • 很公平。关于 VGA 输出场景的好点,我没有想到这一点。
      猜你喜欢
      • 2010-11-09
      • 1970-01-01
      • 1970-01-01
      • 2016-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-22
      相关资源
      最近更新 更多