(iOS Swift) 从 Core Data 获取记录返回致命错误或 nil
Posted
技术标签:
【中文标题】(iOS Swift) 从 Core Data 获取记录返回致命错误或 nil【英文标题】:(iOS Swift) Fetching record from Core Data return fatal error or nil 【发布时间】:2016-07-10 04:27:07 【问题描述】:我开始使用 Swift 为 iPhone 应用程序编写代码,我正面临这个相当令人困惑的障碍,对你们中的一些人来说这可能是微不足道的。我不断收到错误消息,记录是fatal error: unexpectedly found nil while unwrapping an Optional value
或nil
,但是当我检查.sqlite 时记录在那里
让我带你过去
我的.xcdatamodeld的名字是ReviewerApp.xcdatamodeld,和我的app名字ReviewApp一样 ReviewerApp.xcdatamodeld
我的班级名称是Users
,我的实体名称是User
Class: Users, Entity: User
我的属性(用户名、邮箱、密码)都是type: String
,有properties: optional
Users.swift
import Foundation
import CoreData
@objc(Users)
class Users: NSManagedObject
// Insert code here to add functionality to your managed object subclass
@NSManaged var username: String?
@NSManaged var email: String?
@NSManaged var password: String?
signUpController.swift
中的saveUser()
函数
func saveUser()
// create an instance of our managedObjectContext
let moc = DataController().managedObjectContext
// we set up our entity by selecting the entity and context that we're targeting
let entity = NSEntityDescription.insertNewObjectForEntityForName("User", inManagedObjectContext: moc) as! Users
// add our data
entity.setValue(usernameTxtFld.text, forKey: "username")
entity.setValue(emailTxtFld.text, forKey: "email")
entity.setValue(passwordTxtFld.text, forKey: "password")
// we save our entity
do
try moc.save()
//user.append(entity)
print("saved")
catch
fatalError("Failure to save context: \(error)")
SignInController.swift
中的fetch()
函数
let moc = DataController().managedObjectContext
let userFetch = NSFetchRequest(entityName: "User")
do
let fetchedUser = try moc.executeFetchRequest(userFetch) as! [Users]
print(fetchedUser.first!.username!)
catch
fatalError("Failed to fetch person: \(error)")
每次我保存用户注册过程,记录都保存在核心数据中。但每次我试图获取它时:
by: print(fetchedUser.first!.username!) ,控制台中的消息是fatal error: unexpectedly found nil while unwrapping an Optional value
by: print(fetchedUser.first?.username) ,控制台中的消息是nil
非常感谢您的帮助,提前
【问题讨论】:
【参考方案1】:首先我强烈建议您不要使用 '!'代码中的任何位置,因为它会使您的应用程序崩溃(仅适用于静态资源)。你可以使用'if let XXX = YYY as? [...]' 以安全地施放你想要的任何东西...
那么您可能没有在数据库中保存任何内容。你的模型怎么样?您的用户类必须足以满足您构建的模型,否则它将无法工作(这很痛苦),同样在您的模型中,您必须为您的实体提供其类(在“父实体”下方的“类”字段中) .
此外,您不必使用 'entity.setValue(usernameTxtFld.text, forKey: "username")',因为您事先已投射实体。你可以只是'entity.username =usernameTxtFld.text'。
如果我没有提供帮助,请尝试添加 xcdatamodel。
【讨论】:
谢谢你的回复,其实系统提示我加'!'。保存过程很好,我打开 .sqlite 并且数据在那里。我的Class name is set Users'` and
Entity 设置为 User``。我用一些细节和图片更新了我的问题
好吧,我猜它们可能是某个地方的拼写错误……也许是 managedContext? (你有几个吗?)否则我觉得一切都是正确的。
是的,正是我的想法。一切对我来说似乎也是正确的,遗憾的是我们没有开发工具来引导我们,就像我们开发 web 时使用的 firefox 或 chrome 一样。这对我来说是新事物,而且令人困惑......【参考方案2】:
我认为你错过了
let entityDescription = NSEntityDescription.entityForName("User", inManagedObjectContext: moc)
fetchRequest.entity = entityDescription
do
let fetchedUser = try moc.executeFetchRequest(fetchRequest)
print(fetchedUser.first!.username!)
catch
let fetchError = error as NSError
print(fetchError)
如果获取请求成功,该方法将返回一个结果数组。请注意,如果 fetch 请求成功,Core Data 总是返回一个数组,即使我们期望一个结果或者 Core Data 没有找到任何匹配的记录。
有关更多信息和说明,请访问 -
http://code.tutsplus.com/tutorials/core-data-and-swift-managed-objects-and-fetch-requests--cms-25068
【讨论】:
感谢您的回复,实际上我在问这个问题之前已经阅读了链接。我添加了let fetchRequest = NSFetchRequest()
来声明fetchRequest
变量。但是当我尝试打印 fetchedUser.first!.username!
时,错误消息是 Value of type 'AnyObject' has no member 'username'
【参考方案3】:
案件已结案。 DataController.swift 有一些问题。它被调用来保存数据,但是当它被调用来获取数据时,它以某种方式指向不同的地方。所以,我所做的是
-
不再使用 DataController.swift
为我的 AppDelegate.swift 配备 // MARK: - Core Data Saving 支持以保存上下文,因为我没有设置我的应用在开始时包含核心数据
func saveContext()
if managedObjectContext.hasChanges
do
try managedObjectContext.save()
catch
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
abort()
我将保存功能改为
func saveUser()
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
//2
let entity = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: managedContext) as! Users
//3
entity.setValue(usernameTxtFld.text, forKey: "username")
entity.setValue(emailTxtFld.text, forKey: "email")
entity.setValue(passwordTxtFld.text, forKey: "password")
//4
do
try managedContext.save()
//5
message = "Signing up is successful"
alertMessage(message)
catch let error as NSError
print("Could not save \(error), \(error.userInfo)")
并将我的获取功能更改为
func fetch()
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
//2
let fetchRequest = NSFetchRequest(entityName: "Users")
let predicate = NSPredicate(format: "email == %@ AND password == %@", emailTxtFld.text!, passwordTxtFld.text!)
fetchRequest.predicate = predicate
//3
do
let results =
try managedContext.executeFetchRequest(fetchRequest)
user = results as! [Users]
let row = user.count
if row > 0
message = "You're signed in"
//self.performSegueWithIdentifier("signInIdentifier", sender: self)
else
message = "Email & password combination is incorrect!"
alertMessage(message)
catch let error as NSError
print("Could not fetch \(error), \(error.userInfo)")
【讨论】:
以上是关于(iOS Swift) 从 Core Data 获取记录返回致命错误或 nil的主要内容,如果未能解决你的问题,请参考以下文章
iOS:Swift:Core Data:值不使用 Private ManagedObjectContext 存储
Swift - 如何检查现有的 Core Data Store iOS
iOS Swift Core Data 生成带有项目命名空间的 NSManagedObject