使用非可选对象,而 swift 认为它是可选的
Using non-optional object while swift consider it optional
我有一个核心数据NSManagedObject
如下:
public class Records: NSManagedObject {
@NSManaged public var uid: String
@NSManaged public var datetime: Date
}
此外,我有一个通过 UID 检索记录的助手:
func getRecordByUid(uid: String) -> Records!{
do {
let fetchRequest : NSFetchRequest<Records> = Records.createFetchRequest()
fetchRequest.predicate = NSPredicate(format: "uid = %@", uid)
let result: [Records] = try container.viewContext.fetch(fetchRequest)
return result.first
} catch {
print(error.localizedDescription)
return nil
}
}
现在,在我的视图控制器中,我将核心数据对象用作非可选对象(用于添加新记录或编辑现有记录的目的),如下所述:
class AddRecordViewController: UIViewController {
var container: NSPersistentContainer!
var record: Records!
var currentUid = ""
@IBOutlet weak var dateTextField: PickerBasedTextField!
override func viewDidLoad() {
super.viewDidLoad()
// initialise core data
container = NSPersistentContainer(name: "MyModel")
container.loadPersistentStores { (storeDescription, error) in
self.container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
if let error = error {
print("Unsolved error \(error.localizedDescription)")
}
}
if let existingRecord = Facade.share.model.getRecordByUid(uid: currentUid) {
record = existingRecord
} else {
record = Records(context: self.container.viewContext)
}
// datePicker
let formatter = DateFormatter()
formatter.dateStyle = .medium
dateTextField.text = formatter.string(from: record.datetime)
...
}
}
问题是它导致 dateTextField.text = ...
行出错,因为它认为 record
是可选的,但事实并非如此:
(lldb) po record
▿ Optional<Records>
Fatal error: Unexpectedly found nil while unwrapping an Optional value
我该怎么办?
我认为dateTextField
很可能是nil,致命错误与它有关。或者 Records(context: self.container.viewContext)
是一个可失败的初始值设定项,在某些情况下 returns 是一个 nil 对象。
我认为如果将获取和创建包装到一个始终 returns 一个对象的方法中,您的代码会表现得更好。
类似于
func getOrCreateRecord(uid: String) -> Records{
var record: Records?
do {
let fetchRequest : NSFetchRequest<Records> = Records.createFetchRequest()
fetchRequest.predicate = NSPredicate(format: "uid = %@", uid)
let result: [Records] = try container.viewContext.fetch(fetchRequest)
record = result.first
} catch {
print(error.localizedDescription)
}
return record ?? Records(context: container.viewContext)
}
文本字段可能仍然存在问题,但我仍然认为为此逻辑创建包装方法是有意义的。
我有一个核心数据NSManagedObject
如下:
public class Records: NSManagedObject {
@NSManaged public var uid: String
@NSManaged public var datetime: Date
}
此外,我有一个通过 UID 检索记录的助手:
func getRecordByUid(uid: String) -> Records!{
do {
let fetchRequest : NSFetchRequest<Records> = Records.createFetchRequest()
fetchRequest.predicate = NSPredicate(format: "uid = %@", uid)
let result: [Records] = try container.viewContext.fetch(fetchRequest)
return result.first
} catch {
print(error.localizedDescription)
return nil
}
}
现在,在我的视图控制器中,我将核心数据对象用作非可选对象(用于添加新记录或编辑现有记录的目的),如下所述:
class AddRecordViewController: UIViewController {
var container: NSPersistentContainer!
var record: Records!
var currentUid = ""
@IBOutlet weak var dateTextField: PickerBasedTextField!
override func viewDidLoad() {
super.viewDidLoad()
// initialise core data
container = NSPersistentContainer(name: "MyModel")
container.loadPersistentStores { (storeDescription, error) in
self.container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
if let error = error {
print("Unsolved error \(error.localizedDescription)")
}
}
if let existingRecord = Facade.share.model.getRecordByUid(uid: currentUid) {
record = existingRecord
} else {
record = Records(context: self.container.viewContext)
}
// datePicker
let formatter = DateFormatter()
formatter.dateStyle = .medium
dateTextField.text = formatter.string(from: record.datetime)
...
}
}
问题是它导致 dateTextField.text = ...
行出错,因为它认为 record
是可选的,但事实并非如此:
(lldb) po record
▿ Optional<Records>
Fatal error: Unexpectedly found nil while unwrapping an Optional value
我该怎么办?
我认为dateTextField
很可能是nil,致命错误与它有关。或者 Records(context: self.container.viewContext)
是一个可失败的初始值设定项,在某些情况下 returns 是一个 nil 对象。
我认为如果将获取和创建包装到一个始终 returns 一个对象的方法中,您的代码会表现得更好。
类似于
func getOrCreateRecord(uid: String) -> Records{
var record: Records?
do {
let fetchRequest : NSFetchRequest<Records> = Records.createFetchRequest()
fetchRequest.predicate = NSPredicate(format: "uid = %@", uid)
let result: [Records] = try container.viewContext.fetch(fetchRequest)
record = result.first
} catch {
print(error.localizedDescription)
}
return record ?? Records(context: container.viewContext)
}
文本字段可能仍然存在问题,但我仍然认为为此逻辑创建包装方法是有意义的。