gpt4 book ai didi

ios - 界面未使用保存到 core data swift 的最新数据进行更新

转载 作者:行者123 更新时间:2023-11-28 07:06:46 25 4
gpt4 key购买 nike

最近开始学习使用SWIFT语言开发ios应用

所以我开始构建自己的应用程序,其中包含从用户那里收集信息并将其保存\检索到\核心数据的表单

我的主页根据从核心数据中检索到的数据隐藏/显示其按钮并对其进行简单检查,因此数据必须是最新的以避免错误

但是当我将用户添加到核心数据并返回主页时,它会显示按钮,因为没有添加任何内容,但是如果将主页留在其他页面然后返回主页,则会显示最后添加的用户

好像在home出现之前context没有完成数据保存我如何解决这个问题并确保上下文对象完成保存然后显示主页非常感谢

最佳答案

请记住,在执行 segue 之前等待上下文保存可能不是最好的解决方案 - 根据任务的不同,这可能需要很长时间。如果使用这种方法,您应该向用户或 smth 显示一些进度指示器。否则,您的应用 UI 看起来会很僵硬,这是糟糕的用户体验。

无论如何回答你的问题你有3个基本的解决方案:

  • 使用比赛结束
  • 使用授权
  • 使用通知

我假设您使用某种自定义类来加载 CoreData 堆栈,并且您可能具有保存上下文的功能。它可能看起来像这样:

    private func saveContext(completition : (()->() )?) {
if let moc = self.context {
var error : NSError? = nil

if moc.hasChanges && !moc.save(&error){
println(error?.localizedDescription)
abort()
}

//Call delegate method
delegate?.MiniCoreDataStackDidSaveContext()

//Send notification message
defaultCenter.postNotificationName("MyContextDidSaveNotification", object: self)

//Perform completition closure
if let closure = completition {
closure()
}
}
}

然后你像这样使用它:

MyCoreDataStack.saveContext(){
performSegueWithIdentifier(SEGUE_ID,nil)
}

NSNotificationCenter.defaultCenter().addObserverForName("MyContextDidSaveNotification",
object: MyCoreDataStack.saveContext,
queue: NSOperationQueue.mainQueue(),
usingBlock: { _ in performSegueWithIdentifier(SEGUE_ID, sender: nil) }
)

如果您没有任何 Stack - 我已经编写了这个小型单例类作为示例,它缺少适当的错误处理等。在一个私有(private)函数 saveContext 中,它结合了所有三种方法(这只是为了举例,我不建议使用单例模式的委托(delegate))

import CoreData


protocol MiniCoreDataStackDelegate : class {
func MiniCoreDataStackDidSaveContext()
}

@objc(MiniCoreDataStack)
class MiniCoreDataStack {

struct Constants {
static let persistentStoreName = "Store"
static let contextSaveNotification = "MiniCoreDataStackDidSaveContextNotification"
}

private var managedObjectModel : NSManagedObjectModel
private var persistentStoreCoordinator : NSPersistentStoreCoordinator? = nil
private var store : NSPersistentStore?
private let defaultCenter = NSNotificationCenter.defaultCenter()

var defaultContext : NSManagedObjectContext!

var stackIsLoaded : Bool = false

weak var delegate : MiniCoreDataStackDelegate?

class var defaultModel: NSManagedObjectModel {
return NSManagedObjectModel.mergedModelFromBundles(nil)!
}

class var sharedInstance: MiniCoreDataStack {
struct Singleton {
static let instance = MiniCoreDataStack()
}
return Singleton.instance
}


class func storesDirectory() -> NSURL {
let applicationDocumentsDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory,inDomains: .UserDomainMask).last as! NSURL
return applicationDocumentsDirectory
}

private func storeURLForName(name:String) -> NSURL {
return MiniCoreDataStack.storesDirectory().URLByAppendingPathComponent("\(name).sqlite")
}

func localStoreOptions() -> NSDictionary {
return [
NSInferMappingModelAutomaticallyOption:true,
NSMigratePersistentStoresAutomaticallyOption:true
]
}

init( model : NSManagedObjectModel = MiniCoreDataStack.defaultModel){
managedObjectModel = model
}


func openStore(completion:(()->Void)?) {
println("\(NSStringFromClass(self.dynamicType)): \(__FUNCTION__)")

var error: NSError? = nil
let tempPersistenStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)


if let newStore = tempPersistenStoreCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: self.storeURLForName(Constants.persistentStoreName), options: self.localStoreOptions() as [NSObject : AnyObject], error: &error){
self.persistentStoreCoordinator = tempPersistenStoreCoordinator


defaultContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
defaultContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
defaultContext.persistentStoreCoordinator = persistentStoreCoordinator


self.stackIsLoaded = true
println("\(NSStringFromClass(self.dynamicType)): Store loaded")

if let completionClosure = completion {
completionClosure()
}

} else {
println("\(NSStringFromClass(self.dynamicType)): !!! Could not add persistent store !!!")
println(error?.localizedDescription)
}

}

private func saveContext(context: NSManagedObjectContext? = MiniCoreDataStack.sharedInstance.defaultContext!, completition : (()->() )?) {
if !self.stackIsLoaded {
return
}

if let moc = context {
var error : NSError? = nil

if moc.hasChanges && !moc.save(&error){
println(error?.localizedDescription)
abort()
}

//Call delegate method
delegate?.MiniCoreDataStackDidSaveContext()

//Send notification message
defaultCenter.postNotificationName(Constants.contextSaveNotification, object: self)

//Perform completition closure
if let closure = completition {
closure()
}
}
}

func save(context: NSManagedObjectContext? = MiniCoreDataStack.sharedInstance.defaultContext!,completition : (()->() )? ) {
//Perform save on main thread

if (NSThread.isMainThread()) {
saveContext(context: context,completition: completition)
}else {
NSOperationQueue.mainQueue().addOperationWithBlock(){
self.saveContext(context: context, completition : completition)
}
}
}


func fetchResultsControllerForEntity(entity : NSEntityDescription, predicate :NSPredicate? = nil, sortDescriptors:[NSSortDescriptor]? = nil, sectionNameKeyPath:String? = nil, cacheName: String? = nil,inManagedContext context : NSManagedObjectContext? = nil ) ->NSFetchedResultsController {

let fetchRequest = NSFetchRequest()

fetchRequest.entity = entity
fetchRequest.sortDescriptors = sortDescriptors
fetchRequest.predicate = predicate
fetchRequest.fetchBatchSize = 25

var aContext = context ?? self.defaultContext!

let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: aContext, sectionNameKeyPath: sectionNameKeyPath, cacheName: cacheName)

var error: NSError?
if !fetchedResultsController.performFetch(&error){
println("Could not fetch : \(error)")
}

return fetchedResultsController
}

func executeFetchRequest(request : NSFetchRequest, context: NSManagedObjectContext? = nil) -> [NSManagedObject] {
var fetchedObjects = [NSManagedObject]()

let managedContext = context ?? defaultContext

managedContext?.performBlockAndWait{
var error: NSError?
if let result = managedContext?.executeFetchRequest(request, error: &error) {
if let managedObjects = result as? [NSManagedObject] {
fetchedObjects = managedObjects
}
}
if let err = error{
println(err)
}
}

return fetchedObjects
}

func insertEntityWithClassName(className :String, andAttributes attributesDictionary : NSDictionary? = nil, andContext context : NSManagedObjectContext = MiniCoreDataStack.sharedInstance.defaultContext ) -> NSManagedObject {
let entity = NSEntityDescription.insertNewObjectForEntityForName(className, inManagedObjectContext: context) as! NSManagedObject
if let attributes = attributesDictionary {
attributes.enumerateKeysAndObjectsUsingBlock({
(dictKey : AnyObject!, dictObj : AnyObject!, stopBool) -> Void in
entity.setValue(dictObj, forKey: dictKey as! String)
})
}
return entity
}

func deleteEntity(entity: NSManagedObject){
self.defaultContext!.deleteObject(entity)
}

}

使用堆栈:

    //Open store
MiniCoreDataStack.sharedInstance.openStore()
//Insert Entity
let newEntity = MiniCoreDataStack.sharedInstance.insertEntityWithClassName(YourEntityName)
//Saving
MiniCoreDataStack.sharedInstance.save(){
// completition closure
}
//Perform fetch request
MiniCoreDataStack.sharedInstance.executeFetchRequest(YourFetchRequest)

关于ios - 界面未使用保存到 core data swift 的最新数据进行更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30270404/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com