Câu hỏi này xuất hiện mọi lúc.
Một gợi ý là tạo singleton vùng chứa dữ liệu: Một đối tượng được tạo một lần và duy nhất một lần trong vòng đời ứng dụng của bạn và tồn tại trong suốt thời gian ứng dụng của bạn.
Cách tiếp cận này rất phù hợp cho tình huống khi bạn có dữ liệu ứng dụng toàn cầu cần có sẵn / có thể sửa đổi trên các lớp khác nhau trong ứng dụng của mình.
Các cách tiếp cận khác như thiết lập liên kết một chiều hoặc 2 chiều giữa các bộ điều khiển chế độ xem phù hợp hơn với các tình huống mà bạn đang chuyển trực tiếp thông tin / thông báo giữa các bộ điều khiển chế độ xem.
(Xem câu trả lời của nhgrif, bên dưới, để biết các lựa chọn thay thế khác.)
Với một singleton vùng chứa dữ liệu, bạn thêm một thuộc tính vào lớp của mình để lưu trữ một tham chiếu đến singleton của bạn, rồi sử dụng thuộc tính đó bất kỳ lúc nào bạn cần quyền truy cập.
Bạn có thể thiết lập singleton của mình để nó lưu nội dung của nó vào đĩa để trạng thái ứng dụng của bạn vẫn tồn tại giữa các lần khởi chạy.
Tôi đã tạo một dự án demo trên GitHub trình bày cách bạn có thể làm điều này. Đây là liên kết:
Dự án SwiftDataContainerSingleton trên GitHub
Đây là README từ dự án đó:
SwiftDataContainerSingleton
Trình diễn việc sử dụng singleton vùng chứa dữ liệu để lưu trạng thái ứng dụng và chia sẻ nó giữa các đối tượng.
Các DataContainerSingleton
lớp học là singleton thực tế.
Nó sử dụng một hằng số tĩnh sharedDataContainer
để lưu một tham chiếu đến singleton.
Để truy cập singleton, hãy sử dụng cú pháp
DataContainerSingleton.sharedDataContainer
Dự án mẫu xác định 3 thuộc tính trong vùng chứa dữ liệu:
var someString: String?
var someOtherString: String?
var someInt: Int?
Để tải thuộc someInt
tính từ vùng chứa dữ liệu, bạn sẽ sử dụng mã như sau:
let theInt = DataContainerSingleton.sharedDataContainer.someInt
Để lưu một giá trị vào someInt, bạn sẽ sử dụng cú pháp:
DataContainerSingleton.sharedDataContainer.someInt = 3
init
Phương thức của DataContainerSingleton thêm một trình quan sát cho UIApplicationDidEnterBackgroundNotification
. Mã đó trông như thế này:
goToBackgroundObserver = NSNotificationCenter.defaultCenter().addObserverForName(
UIApplicationDidEnterBackgroundNotification,
object: nil,
queue: nil)
{
(note: NSNotification!) -> Void in
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code saves the singleton's properties to NSUserDefaults.
//edit this code to save your custom properties
defaults.setObject( self.someString, forKey: DefaultsKeys.someString)
defaults.setObject( self.someOtherString, forKey: DefaultsKeys.someOtherString)
defaults.setObject( self.someInt, forKey: DefaultsKeys.someInt)
//-----------------------------------------------------------------------------
//Tell NSUserDefaults to save to disk now.
defaults.synchronize()
}
Trong mã quan sát, nó lưu các thuộc tính của vùng chứa dữ liệu vào NSUserDefaults
. Bạn cũng có thể sử dụng NSCoding
, Dữ liệu cốt lõi hoặc nhiều phương pháp khác để lưu dữ liệu trạng thái.
init
Phương thức của DataContainerSingleton cũng cố gắng tải các giá trị đã lưu cho các thuộc tính của nó.
Phần đó của phương thức init trông giống như sau:
let defaults = NSUserDefaults.standardUserDefaults()
//-----------------------------------------------------------------------------
//This code reads the singleton's properties from NSUserDefaults.
//edit this code to load your custom properties
someString = defaults.objectForKey(DefaultsKeys.someString) as! String?
someOtherString = defaults.objectForKey(DefaultsKeys.someOtherString) as! String?
someInt = defaults.objectForKey(DefaultsKeys.someInt) as! Int?
//-----------------------------------------------------------------------------
Các khóa để tải và lưu giá trị vào NSUserDefaults được lưu trữ dưới dạng hằng số chuỗi là một phần của cấu trúc DefaultsKeys
, được định nghĩa như sau:
struct DefaultsKeys
{
static let someString = "someString"
static let someOtherString = "someOtherString"
static let someInt = "someInt"
}
Bạn tham chiếu một trong những hằng số như thế này:
DefaultsKeys.someInt
Sử dụng singleton vùng chứa dữ liệu:
Ứng dụng mẫu này sử dụng trival singleton vùng chứa dữ liệu.
Có hai bộ điều khiển chế độ xem. Đầu tiên là lớp con tùy chỉnh của UIViewController ViewController
và lớp thứ hai là lớp con tùy chỉnh của UIViewController SecondVC
.
Cả hai bộ điều khiển chế độ xem đều có trường văn bản trên chúng và cả hai đều tải một giá trị từ thuộc tính singlelton của vùng chứa dữ liệu someInt
vào trường văn bản trongviewWillAppear
phương thức và cả hai đều lưu giá trị hiện tại từ trường văn bản trở lại `someInt 'của vùng chứa dữ liệu.
Mã để tải giá trị vào trường văn bản nằm trong viewWillAppear:
phương thức:
override func viewWillAppear(animated: Bool)
{
//Load the value "someInt" from our shared ata container singleton
let value = DataContainerSingleton.sharedDataContainer.someInt ?? 0
//Install the value into the text field.
textField.text = "\(value)"
}
Mã để lưu giá trị do người dùng chỉnh sửa trở lại vùng chứa dữ liệu nằm trong textFieldShouldEndEditing
phương thức của bộ điều khiển chế độ xem :
func textFieldShouldEndEditing(textField: UITextField) -> Bool
{
//Save the changed value back to our data container singleton
DataContainerSingleton.sharedDataContainer.someInt = textField.text!.toInt()
return true
}
Bạn nên tải các giá trị vào giao diện người dùng của mình trong viewWillAppear thay vì viewDidLoad để giao diện người dùng của bạn cập nhật mỗi khi bộ điều khiển chế độ xem được hiển thị.