How to make data visible for all view controllers?

余生长醉 提交于 2019-12-21 21:34:17

问题


Let's consider the following case:

I have a tab bar application where tapping each tab bar item takes user to other view that is handled by different view controller(typical pattern).

In one of my controllers I have method that downloads the important data and I want them to be global for whole application. What design pattern should I use?

One way to do that is to store this data using persistence such as core data, but is it the only way to make data visible for all view controllers? Maybe app delegate is able to perform such actions?

How in general you solve such situation where you have some data or variable which should be visible for all view controllers in your project?

Note that I'm not asking about persisting data across launches of the app, I just wonder how to make some data global in terms of the whole project.


回答1:


Dont (emphasize DON'T) use following:

  • Singletons
  • AppDelegate (just another Singleton)
  • NSUserDefaults

Rather Don't:

  • Core Data

Do:

  • pass in either during instantiation or via properties

Why?

The DON'Ts messes up your memory
the Rather Don't messes with several principals of SOLID.

How would you do it correctly:

  • Create a base view controller that has a property that takes your data, make all your view controller inherit from it.

  • subclass UITabBarController

  • if a new view controller is selected, set the data to the view controller

the implementation is a bit tricky, this is from a real world app

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
    }
}

How does the tab bar controller get the data.

Well, that is up to you. It could fetch core data, it could actually pass a fetching manager as data. It could read from disc or network. But for a sane design it should not do it itself but use another class for it. and an instance of this fetcher class should be set from outside the tab bar controller, i.e. from the App Delegate.




回答2:


One easy way would be to make a struct and make it hold variables. Then, you can edit it anytime you would want to. For example:

struct Variables {
   static var number = 4
}

Then you can edit the data inside Variables in any view controller you want by doing this code.

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



回答3:


A cleaner and efficient, although not necessarily different, way to do this is to create a singleton class, e.g. AppData, which you can access in a variety of ways, and which would be available to all your other classes. It has the benefit of separating your app-specific stuff from the app delegate stuff. You might define the class this way:

@interface AppData : NSObject

// Perhaps you'll declare some class methods here & objects...

@end

you can define ivars for the AppData class, and then manage a singleton instance of AppData. Use a class method, e.g. +sharedInstance, to get a handle to the singleton on which you could then call mehods. For example,

[[AppData sharedInstance] someMethod:myArgument];

Your implementation of +sharedInstance can be where you manage the actual creation of the singleton, which the method ultimately returns.




回答4:


Try this simple method,

1) Create a variable in appdelegate.swift that could be visible to all viewcontroller.

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

 ...
 ...
 var Check:String!="" // to pass string
 ...
 ...    
}

2) Create appdelegate instance in any viewcontroller

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
        }
    }



回答5:


Singleton pattern can be useful here. In Swift it can be created something like this:

class SomeManager {
    static let sharedInstance = SomeManager()

    var someData: NSData?
}

And accessing it later in your view controllers as SomeManager.sharedInstance.someData

More info about singletons in Swift and a bit in Objective-C here



来源:https://stackoverflow.com/questions/31592910/how-to-make-data-visible-for-all-view-controllers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!