Це питання постійно виникає.
Однією з пропозицій є створення єдиного контейнера даних: об’єкт, який створюється один раз і лише один раз у житті вашої програми та зберігається впродовж життя вашої програми.
Цей підхід добре підходить для ситуації, коли у вас є глобальні дані програми, які повинні бути доступними / модифікованими для різних класів у вашій програмі.
Інші підходи, такі як встановлення односторонніх або двосторонніх зв’язків між контролерами перегляду, краще підходять для ситуацій, коли ви передаєте інформацію / повідомлення безпосередньо між контролерами перегляду.
(Див. Відповідь nhgrif нижче, щоб дізнатися про інші альтернативи.)
За допомогою контейнера даних singleton ви додаєте властивість до свого класу, яка зберігає посилання на ваш singleton, а потім використовуєте цю властивість у будь-який час, коли вам потрібен доступ.
Ви можете налаштувати свій синглтон так, щоб він зберігав його вміст на диску, щоб стан програми зберігався між запусками.
Я створив демонстраційний проект на GitHub, демонструючи, як ви можете це зробити. Ось посилання:
Проект SwiftDataContainerSingleton на GitHub
Ось README з цього проекту:
SwiftDataContainerSingleton
Демонстрація використання одного контейнера даних для збереження стану програми та обміну ним між об'єктами.
DataContainerSingleton
Клас є фактичним Сінглтоном.
Він використовує статичну константу sharedDataContainer
для збереження посилання на синглтон.
Щоб отримати доступ до синглону, використовуйте синтаксис
DataContainerSingleton.sharedDataContainer
Зразок проекту визначає 3 властивості в контейнері даних:
var someString: String?
var someOtherString: String?
var someInt: Int?
Щоб завантажити someInt
властивість із контейнера даних, слід використовувати такий код:
let theInt = DataContainerSingleton.sharedDataContainer.someInt
Щоб зберегти значення в someInt, слід використати синтаксис:
DataContainerSingleton.sharedDataContainer.someInt = 3
Метод DataContainerSingleton init
додає спостерігача для UIApplicationDidEnterBackgroundNotification
. Цей код виглядає так:
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()
}
У коді спостерігача він зберігає властивості контейнера даних NSUserDefaults
. Ви також можете використовувати NSCoding
Core Data або різні інші методи для збереження даних стану.
Метод DataContainerSingleton init
також намагається завантажити збережені значення для його властивостей.
Ця частина методу init виглядає так:
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?
Ключі для завантаження та збереження значень у NSUserDefaults зберігаються у вигляді рядкових констант, які є частиною структури DefaultsKeys
, визначеної таким чином:
struct DefaultsKeys
{
static let someString = "someString"
static let someOtherString = "someOtherString"
static let someInt = "someInt"
}
Ви посилаєтесь на одну з цих констант так:
DefaultsKeys.someInt
Використання одиночного контейнера даних:
Цей зразок програми тривально використовує одиночний контейнер даних.
Є два контролери перегляду. Перший - це власний підклас UIViewController ViewController
, а другий - власний підклас UIViewController SecondVC
.
Обидва контролери подання мають текстове поле, і обидва завантажують значення із someInt
властивості singlelton контейнера даних у текстове поле у своєму viewWillAppear
методі, і обидва зберігають поточне значення з текстового поля назад у `someInt 'контейнера даних.
Код для завантаження значення в текстове поле знаходиться в viewWillAppear:
методі:
override func viewWillAppear(animated: Bool)
{
let value = DataContainerSingleton.sharedDataContainer.someInt ?? 0
textField.text = "\(value)"
}
Код для збереження відредагованого користувачем значення назад у контейнер даних знаходиться в textFieldShouldEndEditing
методах контролерів подання :
func textFieldShouldEndEditing(textField: UITextField) -> Bool
{
DataContainerSingleton.sharedDataContainer.someInt = textField.text!.toInt()
return true
}
Вам слід завантажувати значення у свій користувальницький інтерфейс у viewWillAppear, а не viewDidLoad, щоб ваш інтерфейс оновлювався кожного разу, коли відображається контролер подання.