คำถามนี้ขึ้นมาตลอดเวลา
ข้อเสนอแนะอย่างหนึ่งคือการสร้าง Singleton ที่เก็บข้อมูล: ออบเจ็กต์ที่สร้างขึ้นเพียงครั้งเดียวและครั้งเดียวในชีวิตของแอปพลิเคชันของคุณและจะคงอยู่ตลอดชีวิตของแอป
วิธีนี้เหมาะอย่างยิ่งสำหรับสถานการณ์เมื่อคุณมีข้อมูลแอปทั่วโลกที่จำเป็นต้องพร้อมใช้งาน / แก้ไขได้ในคลาสต่างๆในแอปของคุณ
แนวทางอื่น ๆ เช่นการตั้งค่าการเชื่อมโยงทางเดียวหรือ 2 ทางระหว่างตัวควบคุมมุมมองจะเหมาะกับสถานการณ์ที่คุณส่งข้อมูล / ข้อความโดยตรงระหว่างตัวควบคุมมุมมอง
(ดูคำตอบของ nhgrif ด้านล่างสำหรับทางเลือกอื่น ๆ )
ด้วย 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
init
วิธีการของ DataContainerSingleton เพิ่มผู้สังเกตการณ์สำหรับไฟล์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
การใช้ Singleton ที่เก็บข้อมูล:
แอปพลิเคชันตัวอย่างนี้ใช้ประโยชน์จากซิงเกิลตันที่เก็บข้อมูล
มีตัวควบคุมมุมมองสองตัว ครั้งแรกเป็น subclass กำหนดเองของ UIViewController ViewController
และคนที่สองเป็น subclass กำหนดเองของ SecondVC
UIViewController
ตัวควบคุมมุมมองทั้งสองมีช่องข้อความอยู่และทั้งคู่โหลดค่าจากคุณสมบัติของคอนเทนเนอร์ข้อมูล singlelton someInt
ลงในช่องข้อความในviewWillAppear
วิธีการของพวกเขาและทั้งคู่บันทึกค่าปัจจุบันจากช่องข้อความกลับไปที่ `` someInt 'ของที่เก็บข้อมูล
รหัสสำหรับโหลดค่าลงในช่องข้อความอยู่ในviewWillAppear:
วิธีการ:
override func viewWillAppear(animated: Bool)
{
let value = DataContainerSingleton.sharedDataContainer.someInt ?? 0
textField.text = "\(value)"
}
รหัสสำหรับบันทึกค่าที่ผู้ใช้แก้ไขกลับไปยังที่เก็บข้อมูลอยู่ในวิธีการของ view controllers textFieldShouldEndEditing
:
func textFieldShouldEndEditing(textField: UITextField) -> Bool
{
DataContainerSingleton.sharedDataContainer.someInt = textField.text!.toInt()
return true
}
คุณควรโหลดค่าลงในอินเทอร์เฟซผู้ใช้ของคุณใน viewWillAppear แทนที่จะเป็น viewDidLoad เพื่อให้ UI ของคุณอัปเดตทุกครั้งที่ตัวควบคุมมุมมองแสดง