如何使所有视图控制器的数据可见?

我们来考虑下面的情况:

我有一个标签栏应用程序,其中点击每个标签栏项目将用户转到由不同视图控制器(典型模式)处理的其他视图。

在我的一个控制器中,我有一个方法来下载重要的数据,我希望它们是整个应用程序的全局。 我应该使用什么devise模式?

一种方法是使用持久性(如核心数据)来存储这些数据,但这是使所有视图控制器都可见的唯一方法吗? 也许应用程序委托能够执行此类操作?

一般情况下,您是如何解决这种情况的,即您的项目中的所有视图控制器都应该显示一些数据或variables?

请注意,我并不是要求在启动应用程序时保留数据,我只是想知道如何在整个项目中创build一些数据。

不要(强调不要)使用以下内容:

  • 单身
  • AppDelegate(只是另一个单身人士)
  • NSUserDefaults的

而不是:

  • 核心数据

做:

  • 在实例化过程中或通过属性传递

为什么?

不要忘记你的记忆
宁可不要混淆与几个校长的固体 。

你会如何正确地做到这一点:

  • 创build一个基本视图控制器,该控制器拥有一个可以获取数据的属性,使所有的视图控制器都可以inheritance它。

  • 子类UITabBarController

  • 如果select新的视图控制器,则将数据设置到视图控制器

实现是有点棘手,这是从一个真实世界的应用程序

class ContentTabBarController : UITabBarController { private var kvoSelectedViewControllerContext: UInt8 = 1 required init(coder aDecoder: NSCoder) { self.addObserver(self, forKeyPath: "selectedViewController", options: .New | .Old | .Initial , context: &kvoSelectedViewControllerContext) } deinit{ self.removeObserver(self, forKeyPath: "selectedViewController") } override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) { if context == &kvoSelectedViewControllerContext { var targetVC : UIViewController? if let viewController = change["new"] as? UIViewController{ if let oldViewController = change["old"] as? UIViewController{ if viewController != oldViewController { targetVC = viewController } } } else { targetVC = self.viewControllers![0] as? UIViewController } self.configureTargetViewController(targetVC) } } override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) self.navigationController?.navigationBar.translucent = false } func configureTargetViewController(viewController: UIViewController?){ //setup data } } 

标签栏控制器如何获取数据。

那么,这取决于你。 它可以读取核心数据,实际上可以将读取pipe理器作为数据。 它可以从光盘或networking读取。 但是对于一个理智的devise,它不应该自己做,而应该使用另一个类。 并且这个fetcher类的一个实例应该从标签栏控制器的外部设置,也就是从App Delegate中设置。

一个简单的方法是创build一个结构体并使其保存variables。 然后,您可以随时编辑它。 例如:

 struct Variables { static var number = 4 } 

然后,您可以通过执行此代码在任何视图控制器中编辑Variables中的数据。

 Variables.number = 6 //or any other number you want 

一个更清洁高效的方式,虽然不一定是不同的,但是可以创build一个单例类 ,例如AppData ,你可以通过各种方式访问​​这个类,而其他类可以使用这个类。 它具有将应用程序特定的东西与应用程序委托的东西分开的好处。 你可以这样定义类:

 @interface AppData : NSObject // Perhaps you'll declare some class methods here & objects... @end 

您可以为AppData类定义ivars,然后pipe理AppData的单例实例。 使用一个类方法,例如+ sharedInstance来获得你可以调用mehods的单例的句柄。 例如,

 [[AppData sharedInstance] someMethod:myArgument]; 

您的+ sharedInstance的实现可以是您pipe理单实例创build的地方,方法最终返回。

单例模式在这里很有用。 在Swift中可以创build如下的东西:

 class SomeManager { static let sharedInstance = SomeManager() var someData: NSData? } 

稍后在视图控制器中以SomeManager.sharedInstance.someData访问它

有关Swift中singletons的更多信息,以及Objective-C中的一些信息

试试这个简单的方法,

1)在appdelegate.swift中创build一个对所有viewcontroller都可见的variables。

 import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { ... ... var Check:String!="" // to pass string ... ... } 

2)在任何viewcontroller中创buildappdelegate实例

viewcontroller1.swift

 import UIKit class ViewController: UIViewController { let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate ... ... override func viewDidLoad() { super.viewDidLoad() ... var tmp = "\(appDelegate.Check)" appDelegate.Check="Modified" } } 

Viewcontroller2.swift

 import UIKit class ViewController: UIViewController { let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate ... ... override func viewDidLoad() { super.viewDidLoad() ... var getdata = "\(appDelegate.Check)" println("Check data : \(getdata)") // Output : Check data : Modified } }