从 appdelegate 更新视图控制器 - 最佳实践?
Posted
技术标签:
【中文标题】从 appdelegate 更新视图控制器 - 最佳实践?【英文标题】:update viewcontroller from appdelegate - best practice? 【发布时间】:2015-03-21 03:04:45 【问题描述】:我正在使用 iBeacons 在 AppDelegate.swift 中实现 CoreLocation 方法(方法在 AppDelegate 中实现以确保应用程序后台功能)
在“ViewController.swift”附带的 SingleView 应用程序中,将数据从 AppDelegate 传递到 ViewController 以更新视图(例如 UIImages、UILabels 或 UITableViews)的最佳实践是什么?
我已经成功实现了两种不同的方法:
1) 委托,通过在 AppDelegate.swift 中触发 Viewcontroller 委托方法:
protocol BeaconLocationDelegate func minorBeaconChanged(minorValue:NSNumber)
var locationDelegate: BeaconLocationDelegate
locationDelegate?.minorBeaconChanged(nearestBeacon.minor)
ViewController.swift:
在 viewDidLoad 方法中:
(UIApplication.sharedApplication().delegate as AppDelegate).locationDelegate = self
(我觉得这看起来很丑 - 有没有更好的方法将此属性声明为委托?)
协议实现:
func minorBeaconChanged(minorValue: NSNumber)
// do fancy stuff here
2) 通过在 AppDelegate 中创建对 ViewController 的引用:
let viewController:ViewController = window!.rootViewController as ViewController
viewController.doSomethingFancy()
这两种方法对我来说都很好,但我认为通过委托的第一种方法更优雅,并且一旦你有多个 ViewControllers 是更好的选择。
有什么建议吗?
【问题讨论】:
【参考方案1】:我认为第二种解决方案要容易得多。它还确保视图控制器不会耗尽内存(被“释放”)并且应用程序委托不会尝试联系不存在的对象。
另外,在多个控制器的情况下,我不理解委托参数。在这种情况下,您将不得不有多个代表,这确实不是一个理想的情况。或者您将不得不从外部将委托更改为不同的视图控制器 - 也不是很优雅且风险很大。
对于多视图控制器场景,我建议通过NSNotificationCenter
进行通知。这是一个松耦合,它确保只有那些需要做出反应的对象才能接收到消息。视图控制器应该在创建时开始监听通知,并在通知中心消失时从通知中心注销。
【讨论】:
这也是最佳做法吗?我认为委托将是最佳选择,部分原因在于 MVC 概念,其中对视图的更新主要由委托方法触发,从而将视图与模型分离。 我对处理 appdelegate 中的数据也不是很有信心。寻找将其移至单独班级的方法,但仍不确定如何。目标是从肮脏的 hack 转变为良好且可重用的代码。 建议的解决方案不违反 MVC。我们根本没有讨论过这个模型。这只是您希望将控制器与应用程序委托(应用程序的“全局”类)耦合到何种程度的问题。非常松散(通知)或紧密(保留的财产)。在您的用例中,没有理由反对紧密耦合。 您的第二条评论涉及一个不同的问题,也许您应该在单独的问题中解决。欢迎来到 ***。开始通过投票和/或接受答案来表示赞赏。【参考方案2】:这个怎么样?
在 AppDelegate 中
var minorBeaconChanged: NSNumber -> () = minor in
并在位置更新时调用此方法。
在 ViewController 的 viewWillAppear 中
( UIApplication.sharedApplication().delegate as? AppDelegate )!.minorBeaconChanged = minor in
// Do with minor
编辑:2015 年 8 月 27 日
如果你想拥有多个观察者。
在 AppDelegate 中
var minorBeaconObservers: [ NSNumber -> () ] = []
并用'minor'调用minorBeaconObservers中的所有项目
在 ViewController 的 viewWillAppear 中
( UIApplication.sharedApplication().delegate as? AppDelegate )!.minorBeaconObservers.append(
minor in
// Do with minor
)
【讨论】:
这样minorBeaconChanged只能有1个观察者,但我现在正在使用它。以上是关于从 appdelegate 更新视图控制器 - 最佳实践?的主要内容,如果未能解决你的问题,请参考以下文章