ios - sata - software de controlador de dispositivo windows 7
¿Cómo hacer que los datos sean visibles para todos los controladores de vista? (5)
Consideremos el siguiente caso:
Tengo una aplicación de barra de pestañas donde tocar cada elemento de la barra de pestañas lleva al usuario a otra vista que maneja un controlador de vista diferente (patrón típico).
En uno de mis controladores tengo un método que descarga los datos importantes y quiero que sean globales para toda la aplicación. ¿Qué patrón de diseño debo usar?
Una forma de hacerlo es almacenar esta información usando persistencia como datos centrales, pero ¿es la única manera de hacer que los datos sean visibles para todos los controladores de vista? ¿Tal vez el delegado de la aplicación puede realizar tales acciones?
¿Cómo, en general, resuelve esa situación en la que tiene algunos datos o variables que deberían estar visibles para todos los controladores de vista en su proyecto?
Tenga en cuenta que no estoy preguntando sobre la persistencia de datos en los lanzamientos de la aplicación, solo me pregunto cómo hacer que algunos datos sean globales en términos de todo el proyecto.
No (enfatizar NO) utilice lo siguiente:
- Singletons
- AppDelegate (solo otro Singleton)
- NSUserDefaults
Más bien no:
- Datos principales
Hacer:
- pasar ya sea durante la instanciación o a través de propiedades
¿Por qué?
Los DON''Ts arruinan tu memoria
el Rather No te metas con varios principios de SOLID .
¿Cómo lo harías correctamente?
Cree un controlador de vista base que tenga una propiedad que tome sus datos, haga que todo su controlador de vista herede de ella.
subclase UITabBarController
si se selecciona un nuevo controlador de vista, establezca los datos en el controlador de vista
la implementación es un poco complicada, esto es de una aplicación real
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
}
}
¿Cómo obtiene el controlador de la barra de pestañas los datos?
Bueno, eso depende de ti. Podría obtener datos básicos, en realidad podría pasar un administrador de búsqueda como datos. Podría leer desde el disco o la red. Pero para un diseño sensato, no debería hacerlo solo, sino usar otra clase para él. y una instancia de esta clase de captador debe configurarse desde fuera del controlador de la barra de pestañas, es decir, desde el delegado de la aplicación.
Prueba este método simple,
1) Cree una variable en appdelegate.swift que pueda ser visible para todos viewcontroller.
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
...
...
var Check:String!="" // to pass string
...
...
}
2) Crear instancia de appdelegate en cualquier controlador de vista
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
}
}
Una manera fácil sería hacer una estructura y hacer que contenga variables. Luego, puede editarlo en cualquier momento que desee. Por ejemplo:
struct Variables {
static var number = 4
}
Luego puede editar los datos dentro de Variables en cualquier controlador de vista que desee al hacer este código.
Variables.number = 6 //or any other number you want
Una manera más limpia y eficiente, aunque no necesariamente diferente, de hacer esto es crear una clase singleton , por ejemplo, AppData
, a la que pueda acceder de varias maneras, y que esté disponible para todas sus otras clases. Tiene el beneficio de separar las cosas específicas de la aplicación del material de delegado de la aplicación. Puede definir la clase de esta manera:
@interface AppData : NSObject
// Perhaps you''ll declare some class methods here & objects...
@end
puede definir ivars para la clase AppData y luego administrar una instancia singleton de AppData. Utilice un método de clase, por ejemplo, + sharedInstance , para obtener un control para el singleton en el que luego podría llamar a mehods. Por ejemplo,
[[AppData sharedInstance] someMethod:myArgument];
Su implementación de + sharedInstance puede ser donde usted gestiona la creación real del singleton, que finalmente devuelve el método.
El patrón Singleton puede ser útil aquí. En Swift se puede crear algo como esto:
class SomeManager {
static let sharedInstance = SomeManager()
var someData: NSData?
}
Y accediendo más tarde en sus controladores de vista como SomeManager.sharedInstance.someData
Más información sobre singletons en Swift y un poco en Objective-C aquí