To pytanie pojawia się cały czas.
Jedną z sugestii jest utworzenie pojedynczego kontenera danych: obiektu, który jest tworzony raz i tylko raz w życiu aplikacji i utrzymuje się przez cały okres użytkowania aplikacji.
To podejście jest dobrze dostosowane do sytuacji, gdy masz globalne dane aplikacji, które muszą być dostępne / modyfikowalne w różnych klasach aplikacji.
Inne podejścia, takie jak konfigurowanie jednokierunkowych lub dwukierunkowych połączeń między kontrolerami widoku, są lepiej dostosowane do sytuacji, w których przekazujesz informacje / komunikaty bezpośrednio między kontrolerami widoku.
(Zobacz odpowiedź nhgrif poniżej, aby poznać inne alternatywy.)
W przypadku pojedynczego kontenera danych dodajesz właściwość do swojej klasy, która przechowuje odwołanie do singletonu, a następnie używasz tej właściwości w dowolnym momencie, gdy potrzebujesz dostępu.
Możesz skonfigurować singleton tak, aby zapisywał jego zawartość na dysku, aby stan aplikacji utrzymywał się między uruchomieniami.
Stworzyłem projekt demonstracyjny na GitHub pokazujący, jak możesz to zrobić. Tutaj jest link:
Projekt SwiftDataContainerSingleton na GitHub
Oto README z tego projektu:
SwiftDataContainerSingleton
Demonstracja użycia singletonu kontenera danych do zapisywania stanu aplikacji i udostępniania go między obiektami.
DataContainerSingletonKlasa jest rzeczywista Singleton.
Używa stałej statycznej, sharedDataContaineraby zapisać odwołanie do singletona.
Aby uzyskać dostęp do singletona, użyj składni
DataContainerSingleton.sharedDataContainer
Przykładowy projekt definiuje 3 właściwości w kontenerze danych:
var someString: String?
var someOtherString: String?
var someInt: Int?
Aby załadować someIntwłaściwość z kontenera danych, należy użyć następującego kodu:
let theInt = DataContainerSingleton.sharedDataContainer.someInt
Aby zapisać wartość w someInt, użyjesz składni:
DataContainerSingleton.sharedDataContainer.someInt = 3
Metoda DataContainerSingleton initdodaje obserwatora dla UIApplicationDidEnterBackgroundNotification. Ten kod wygląda następująco:
goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationDidEnterBackgroundNotification,
object: nil,
queue: nil)
{
(note: NSNotification!) -> Void in
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject( self.someString, forKey: DefaultsKeys.someString)
defaults.setObject( self.someOtherString, forKey: DefaultsKeys.someOtherString)
defaults.setObject( self.someInt, forKey: DefaultsKeys.someInt)
defaults.synchronize()
}
W kodzie obserwatora zapisuje właściwości kontenera danych NSUserDefaults. Możesz także użyć NSCoding, Core Data lub różnych innych metod zapisywania danych stanu.
Metoda DataContainerSingleton initpróbuje również załadować zapisane wartości dla jej właściwości.
Ta część metody init wygląda następująco:
let defaults = NSUserDefaults.standardUserDefaults()
someString = defaults.objectForKey(DefaultsKeys.someString) as! String?
someOtherString = defaults.objectForKey(DefaultsKeys.someOtherString) as! String?
someInt = defaults.objectForKey(DefaultsKeys.someInt) as! Int?
Klucze do ładowania i zapisywania wartości w NSUserDefaults są przechowywane jako stałe łańcuchowe, które są częścią struktury DefaultsKeys, zdefiniowane w następujący sposób:
struct DefaultsKeys
{
static let someString = "someString"
static let someOtherString = "someOtherString"
static let someInt = "someInt"
}
Odwołujesz się do jednej z tych stałych w ten sposób:
DefaultsKeys.someInt
Korzystanie z singletonu kontenera danych:
Ta przykładowa aplikacja umożliwia potrójne użycie pojedynczego kontenera danych.
Istnieją dwa kontrolery widoku. Pierwsza to niestandardowa podklasa UIViewController ViewController, a druga to niestandardowa podklasa UIViewController SecondVC.
Oba kontrolery widoku mają na sobie pole tekstowe i oba ładują wartość z właściwości singlelton kontenera danych someIntdo pola tekstowego w swojej viewWillAppearmetodzie i oba zapisują bieżącą wartość z pola tekstowego z powrotem do „someInt” kontenera danych.
Kod do załadowania wartości do pola tekstowego znajduje się w viewWillAppear:metodzie:
override func viewWillAppear(animated: Bool)
{
let value = DataContainerSingleton.sharedDataContainer.someInt ?? 0
textField.text = "\(value)"
}
Kod umożliwiający zapisanie wartości edytowanej przez użytkownika z powrotem w kontenerze danych znajduje się w textFieldShouldEndEditingmetodach kontrolerów widoku :
func textFieldShouldEndEditing(textField: UITextField) -> Bool
{
DataContainerSingleton.sharedDataContainer.someInt = textField.text!.toInt()
return true
}
Wartości należy ładować do interfejsu użytkownika w viewWillAppear zamiast viewDidLoad, aby interfejs użytkownika był aktualizowany za każdym razem, gdy wyświetlany jest kontroler widoku.