AppDelegate 在启动时最后实例化
Posted
技术标签:
【中文标题】AppDelegate 在启动时最后实例化【英文标题】:AppDelegate instantiated last on launch 【发布时间】:2015-03-21 16:30:31 【问题描述】:我很擅长编写 ios 应用程序,但 OS X 出人意料地显得有些陌生。
这是前面的问题(请继续阅读以了解上下文):
当我的应用程序使用在我的应用程序目标的部署信息下的主界面字段中设置的 .xib 启动时,为什么 AppDelegate 在 ViewControllers 之后被实例化?
上下文(没有双关语):
我问的原因是因为我正在使用 Core Data(请不要为这个决定烦恼),并且通常您会在 AppDelegate 中保留一个指向 MOC(托管对象上下文)的指针。我的一个控制器正在尝试获取此 MOC 实例变量,但 AppDelegate 实例尚未出现,因此我的应用在启动后不会显示数据。
AppDelegate 和两个 ViewController 在 .xib 中。 VC 与拆分视图中的视图挂钩。他们正在尝试使用 viewDidLoad 中的 MOC 进行查询。他们像这样访问 AppDelegate:
let delegate = NSApplication.sharedApplication().delegate as AppDelegate
let moc = delegate.managedObjectContext
当sharedApplication()
的.delegate
属性返回nil 时,这将崩溃。
我尝试从 applicationDidFinishLaunching
中的 .xib 制作一个 NSWindowController 并从 Main Interface 字段中删除 .xib,但随后根本没有调用 applicationDidFinishLaunching
。
我已确保在 IB 中从应用程序和文件所有者 (NSApplcation) 委托 IBOutlets 到 AppDelegate 的所有连接都已建立。
更新 - 2015 年 3 月 31 日
Stephen Darlington 在下面的回答为我/这个案例提供了一个很好的解决方案。据我了解,实际上按照他的建议设置 MOC 会更好。
如果有一个正确答案可以解释为什么 AppDelegate 在启动过程的稍后时间被实例化,我会将其标记为正确,而不是 Stephen 的。谢谢斯蒂芬!
【问题讨论】:
您在哪里或如何创建 ViewControllers 的实例?视图控制器实例是否也驻留在主 nib 文件中?当你说“我的一个控制器正在尝试获取这个 MOC 实例变量但 AppDelegate 实例还没有出现”时,这个视图控制器是否有一个IBOutlet
到 AppDelegate
,和/或在什么方法视图控制器是否尝试访问 AppDelegate
(例如,init
、awakeFromNib
等)?
感谢您指出宝贵的缺失信息@NSGod。我已编辑我的问题以回答您的问题。
在 AppDelegate 类中尝试 @NSApplicationMain
尝试强制它更快地初始化委托实例?
@stevesliva 被放置在 AppDelegate 的顶部,在 Xcode 模板的类定义之外。那是对的吗?如果是这样,问题仍然存在。
【参考方案1】:
“简单”的解决方案是让managedObjectContext
在 MOC 不存在的情况下创建一个(即,将其从属性更改为方法)。这样,无论哪个代码先到达那里,堆栈都将可用。
(关于在应用程序委托中创建核心数据堆栈和像那样访问应用程序委托的讲座我将不谈!)
【讨论】:
太棒了!谢谢!这就是我的目标。你会建议我把指向 MOC 的指针放在哪里?我当然必须在某些课程上将其设为静态?我什至敢说 AppDel ...... p.s.谢谢你饶了我?? 最近我成功使用了SLCoreDataStack。但即使您不喜欢这样,将堆栈保留在单独的类中也是一个不错的想法。 太好了,再次感谢!我对是否将您的答案标记为正确感到困惑,因为它实际上并不能解决我的问题,但确实提供了一个适合我的替代解决方案。我在考虑其他人在寻找为什么 AppDel 在稍后实例化的原因..【参考方案2】:这是另一个选项 不必继承 NSApplication:
不要将您的视图控制器放在您设置为主界面的 .xib 中,只需在其中放置主菜单(菜单栏)、AppDelegate 和字体管理器即可。 然后在其他 .xib 中创建您的视图控制器。 然后在applicationDidFinishLaunching
方法中,从它们的 .xib 文件中初始化视图控制器。
【讨论】:
【参考方案3】:我在设置 Parse 时也遇到了这个问题。为了解决这个问题,我简单地将 NSApplication 子类化并将其设置为 Info.plist
中的 Principle class
。在您的 NSApplication 子类中,重写 init 方法并初始化 Parse 或您需要的任何其他内容。
【讨论】:
以上是关于AppDelegate 在启动时最后实例化的主要内容,如果未能解决你的问题,请参考以下文章
我们可以在AppDelegate中实例化核心数据的单个对象并在整个应用程序中使用它吗?
使用 AppDelegate 中的 Storyboard 以编程方式实例化视图控制器