Tôi hiện đang làm việc với một lớp con NSPersistentDocument
sử dụng NSOperation
để nhập dữ liệu dưới nền. Theo tài liệu, tôi quan sát số NSManagedObjectContextDidSaveNotification
sau khi lưu trong tác vụ nền và truyền thông báo tới NSManagedObjectContext
trong luồng chính bằng cách sử dụng -mergeChangesFromContextDidSaveNotification:
.Dữ liệu cốt lõi và NSOperation
Mọi thứ hoạt động tốt, nhưng nó thể hiện luồng công việc lạ đối với người dùng đang nhập dữ liệu vào tài liệu mới. Họ cần phải lưu một tài liệu trống trước khi thực hiện việc nhập (nếu không thì -save:
không thành công vì tài liệu chưa định cấu hình URL cho NSPersistentStoreCoordinator
.) Tôi không thấy cách nào khác ngoài trình hướng dẫn "thiết lập tài liệu mới" đảm bảo rằng -writeToURL:ofType:forSaveOperation:originalContentsURL:error:
được gọi trước khi nhập.
Ngoài ra, có vẻ như nhiệm vụ nhập trong nền không bao gồm việc sử dụng NSUndoManager
trên chuỗi chính. (Tôi cho rằng không an toàn để chia sẻ trình quản lý hoàn tác của bối cảnh đối tượng được quản lý qua các chủ đề.) Từ quan điểm của người dùng, không có cách nào để hoàn tác tất cả các đối tượng mới được tạo trong khi nhập.
Tôi đã đọc cả Sách hướng dẫn lập trình dữ liệu chính và Marcus Zarra, nhưng tôi vẫn còn mới đối với khía cạnh này của khung. Hy vọng rằng, tôi đã bỏ qua điều gì đó: nếu không, tôi sẽ điều chỉnh ứng dụng của mình theo những hạn chế này (lợi ích của Core Data vượt xa những giới hạn giao diện người dùng này.)
Cảm ơn bạn đã dành thời gian!
-
Dựa trên đề nghị Peter Hosey của dưới đây, tôi đã thêm đoạn mã sau để tạo ra một cửa hàng khăng khăng tạm thời trước khi nhập khẩu:
NSPersistentStoreCoordinator *persistentStoreCoordinator = [self.managedObjectContext persistentStoreCoordinator];
if ([[persistentStoreCoordinator persistentStores] count] == 0) {
// create an in-memory store to use temporarily
NSError *error;
NSPersistentStore *persistentStore = [persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:&error];
if (! persistentStore) {
NSLog(@"error = %@", error); // TODO: better error handling
}
}
Sau đó, sau khi một file được chọn trong lưu bảng điều khiển, lưu trữ lâu dài tạm thời được di chuyển đến một cửa hàng SQLite tại URL đã chọn:
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation originalContentsURL:(NSURL *)absoluteOriginalContentsURL error:(NSError **)error
{
NSPersistentStoreCoordinator *persistentStoreCoordinator = [self.managedObjectContext persistentStoreCoordinator];
for (NSPersistentStore *persistentStore in [persistentStoreCoordinator persistentStores]) {
if (persistentStore.type == NSInMemoryStoreType) {
// migrate the in-memory store to a SQLite store
NSError *error;
NSPersistentStore *newPersistentStore = [persistentStoreCoordinator migratePersistentStore:persistentStore toURL:absoluteURL options:nil withType:NSSQLiteStoreType error:&error];
if (! newPersistentStore) {
NSLog(@"error = %@", error); // TODO: better error handling
}
}
}
return [super writeToURL:absoluteURL ofType:typeName forSaveOperation:saveOperation originalContentsURL:absoluteOriginalContentsURL error:error];
}
Khi bạn sử dụng máy Mac, bạn có thể sử dụng bộ nhớ trong cửa hàng bộ nhớ không, sau đó chuyển ngữ cảnh để sử dụng kho lưu trữ tệp khi sẵn sàng? Ở trên cũng sẽ giải quyết vấn đề với hoàn tác, như bạn chỉ có thể phân chia với toàn bộ bối cảnh ngăn xếp nếu cần thiết. Có vẻ như trong khi tôi đang viết, mọi người đều viết giống nhau :) – Jonathan