1

我根据这篇博客文章(Swift 中)设计了一个核心数据堆栈,其中我有两个NSManagedObjectContext实例,一个主队列上下文(NSMainQueueConcurrencyType)和一个私有队列上下文(NSPrivateQueueConcurrencyType),其中主上下文的工作是处理与用户交互相关的所有事情(编辑,向用户呈现数据)和私有上下文的唯一工作是写入磁盘。

为了使管理堆栈尽可能简单,我集成了Magical RecordOvercoatMantle。我将所有这些分为两个类,一个 Core Data 单例堆栈(基于 Magical Record 构建)和一个网络管理器单例(构建在 Overcoat 之上,而后者又构建在 Mantle 之上)。

Core Data 堆栈如下所示:

import UIKit
import CoreData
import MagicalRecord

class CoreData: NSObject {

    enum StackType: Int {
        case Default, AutoMigrating, iCloud, inMemory
    }

    static let sharedStack = CoreData()
    private override init() {}

    var type: StackType = .Default

    func setupStackWithType(type: StackType, withName name: String = MagicalRecord.defaultStoreName()) {
        self.type = type
        switch self.type {
        case .Default:
            MagicalRecord.setupCoreDataStackWithStoreNamed(name)
        case .AutoMigrating:
            MagicalRecord.setupCoreDataStackWithAutoMigratingSqliteStoreNamed(name)
        case .iCloud:
            if let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first {
                let url = NSURL(fileURLWithPath: documentsPath)
                MagicalRecord.setupCoreDataStackWithiCloudContainer(name, localStoreAtURL: url)
            } else {
                print("Error: could not find documents directory")
            }
        case .inMemory:
            MagicalRecord.setupCoreDataStackWithInMemoryStore()
        }
    }

    func setupStackWithStoreName(storeName: String, automigrating: Bool = true) {
        if automigrating {
            MagicalRecord.setupCoreDataStackWithAutoMigratingSqliteStoreNamed(storeName)
        } else {
            MagicalRecord.setupAutoMigratingCoreDataStack()
        }
    }

    func saveWithBlock(block: (NSManagedObjectContext!) -> ()) {
        MagicalRecord.saveWithBlock(block, completion: {
            (success, error) in

        })
    }

    func cleanUp() {
        MagicalRecord.cleanUp()
    }

    var managedObjectContext: NSManagedObjectContext {
        return NSManagedObjectContext.MR_defaultContext()
    }
    var privateContext: NSManagedObjectContext {
       return NSManagedObjectContext.MR_rootSavingContext()
    }
    var coordinator: NSPersistentStoreCoordinator {
        return NSPersistentStoreCoordinator.MR_defaultStoreCoordinator()
    }

    var persistentStore: NSPersistentStore {
        return NSPersistentStore.MR_defaultPersistentStore()
    }
}

我的网络管理员看起来像:

import UIKit
import Overcoat
import MTLManagedObjectAdapter

class NetworkManager: OVCManagedHTTPSessionManager {

    static let singleton = NetworkManager(baseURL: NSURL(string: Config.ServerBaseEndpoint), managedObjectContext: nil, sessionConfiguration: {
        let config = NSURLSessionConfiguration.defaultSessionConfiguration()
        config.timeoutIntervalForRequest = 15
        config.timeoutIntervalForResource = 15
        return config
    }())

    private override init(baseURL url: NSURL?, managedObjectContext context: NSManagedObjectContext?, sessionConfiguration configuration: NSURLSessionConfiguration?) {
        super.init(baseURL: url, managedObjectContext: context, sessionConfiguration: configuration)
        self.responseSerializer.acceptableContentTypes = ["text/html", "application/json", "application/xml", "image/png"]
        self.securityPolicy = AFSecurityPolicy(pinningMode: .None)
        self.securityPolicy.allowInvalidCertificates = true
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    // MARK: - OVCHTTPSessionManager

    override class func modelClassesByResourcePath() -> [String: AnyClass] {
        return [Types.RestApi.Post.rawValue:Post.self, "\(Types.RestApi.Post.rawValue)/*": Post.self]
    }
 }

我不能完全理解的是 1)这两个类如何协同工作,以及 2)关于核心数据堆栈、要保存的上下文、在哪个上下文上做什么等。

对于NetworkManager.swift(需要将NSManagedObjectContext模型持久化到):

我用哪个上下文来初始化管理器?我的假设是,如果您发出网络请求并且 JSON 被转换为中间Mantle模型并从那里转换为NSManagedObejct实例,那么这些实例应该直接保存到私有队列上下文,在这种情况下完全绕过主队列上下文。

谈论时CoreData.swift

1) Magical Record 具有saveWithBlock创建本地上下文并将其传播到根上下文的方法(在这种情况下,根上下文是私有队列上下文),但不清楚在块内应该做什么工作。

在他们的文档中,他们给出了这个例子:

Person *person = ...;

[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){

  Person *localPerson = [person MR_inContext:localContext];
  localPerson.firstName = @"John";
  localPerson.lastName = @"Appleseed";

}];

他们Person在保存块之外创建一个对象,然后在本地上下文中重新制作实体,然后编辑它的属性。但是在我的情况下,所有Person对象都是 的实例MTLModel,而不是NSManagedObjectMTLManagedObjectAdapter当我创建一些模型对象时,因为它不是核心数据对象,所以在我用来将模型转换为NSManagedObject实例之前,它不会被插入任何类型的上下文中。

最好的方法似乎是创建MTLModel实例,进行任何需要的编辑,然后 1)在内部saveWithBlock将新创建的托管对象直接插入本地上下文并让它向上传播,或者 2)插入对象放入私有队列上下文并保存。

2)我真的需要使用主队列上下文来保存和编辑吗?正如我之前所说,Mantle 将模型类作为子类,MTLModel然后将它们映射到NSManagedObject实例中,因此我可以直接保存到 Private Queue Context(其唯一的工作就是写入磁盘)是有道理的

3)如果我不需要使用主队列上下文进行保存/编辑,它不会成为我用于获取的上下文NSManagedObjects(鉴于私有队列的工作是写入磁盘和保存/编辑功能Mantle 的中间模型结构似乎使 Main Queue Context 过时了)?

4

0 回答 0