ios 如何使用 Magical Record 创建和更新对象并在不使用 contextForCurrentThread 的情况下保存它们
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19251246/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I use Magical Record to create & update objects and save them without using contextForCurrentThread
提问by Paul Sturgess
I just read the author of MagicalRecord's blog post on Why contextForCurrentThread Doesn't work in MagicalRecord.
我刚刚阅读了 MagicalRecord 博客文章的作者,关于为什么 contextForCurrentThread 在 MagicalRecord 中不起作用。
contextForCurrentThread
is deprecated and saveWithBlock
should be used instead because it creates a safe new NSManagedObjectContext
for the relevant thread.
contextForCurrentThread
已弃用,saveWithBlock
应改为使用,因为它NSManagedObjectContext
为相关线程创建了一个安全的新线程。
I've been using contextForCurrentThread
extensively in my app so far. However, I'm having trouble figuring out how to use saveWithBlock
instead as my fetching and saving are not necessarily happening sequentially.
contextForCurrentThread
到目前为止,我一直在我的应用程序中广泛使用。但是,我无法弄清楚如何使用,saveWithBlock
因为我的获取和保存不一定按顺序发生。
Currently I'm doing things like:
目前我正在做这样的事情:
localContext = NSManagedObjectContext.MR_contextForCurrentThread
person = Person.MR_createInContext(localContext)
person.name = "John Smith"
The user may then browse around the app, different controllers, views etc. are displayed. Other objects may be created using a similar method to the code above.
然后用户可以浏览应用程序,显示不同的控制器、视图等。可以使用与上述代码类似的方法创建其他对象。
Then at some arbitrary point in the future, when the user decides to save, I run this method:
然后在将来的某个任意时刻,当用户决定保存时,我运行此方法:
localContext = NSManagedObjectContext.MR_contextForCurrentThread
localContext.MR_saveToPersistentStoreWithCompletion(
lambda { |success, error|
# ...
}
)
What is the recommended way to create & update objects and then save them without using contextForCurrentThread
?
创建和更新对象然后在不使用的情况下保存它们的推荐方法是什么contextForCurrentThread
?
采纳答案by casademora
So, I use objective C as opposed to RubyMotion, but you should be able todo things like this:
因此,我使用目标 C 而不是 RubyMotion,但您应该能够执行以下操作:
MagicalRecord.saveWithBlock(
lambda { |localContext|
person = Person.MR_createInContext(localContext)
#update person stuff here
}
)
EDIT
编辑
If you want to save the context later, you just need to hold on to it:
如果你想稍后保存上下文,你只需要坚持下去:
// Somewhere in your ViewController, etc
NSManagedObjectContext *context = [NSManagedObjectContext MR_confinementContext];
// Somewhere else
Person *p = [Person MR_createInContext:context];
// And in yet another method
[context MR_saveToPersistentStoreAndWait];
The main idea here is that you just need to hold on to the context and perform your operations on it when you're ready. If you want a background save to occur, you an use the following method:
这里的主要思想是,您只需要保持上下文并在准备好时对其执行操作。如果要进行后台保存,可以使用以下方法:
[context MR_saveToPersistentStoreCompletion:^(BOOL success, NSError *error){
//called on the main thread when save is complete
}];
回答by lbsweek
here is a tutorial for new api: http://ablfx.com/blog/article/2here is the refence: http://cocoadocs.org/docsets/MagicalRecord/2.1/
这是新 api 的教程:http://ablfx.com/blog/article/2 这里是参考:http://cocoadocs.org/docsets/MagicalRecord/2.1/
init
[MagicalRecord setupCoreDataStackWithStoreNamed:@"MyDatabase.sqlite"];
dealloc
[MagicalRecord cleanUp];
insert
Person *alex = [Person MR_createEntity]; alex.name = @"Alex"; alex.age = @23;
select
/Retrieve all for aNSManagedObject subclass
NSArray *people = [Person MR_findAll];
//Retrieve first record
Person *aPerson = [Person MR_findFirst];
//Retrieve records conditionally & sort
NSArray *people = [Person MR_findByAttribute:@"name" withValue:@"alex" andOrderBy:@"age" ascending:YES];
update
//Updating a retrieved entity is as easy as manipulating it's properties
aPerson.age = @56;
delete
//Remove all records
[Person MR_truncateAll];
//Delete single record, after retrieving it
[alex MR_deleteEntity];
save
//For any entities to actually be saved / updated / deleted on disk call following method
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
//Again check the MagicalRecord repo for more save options
在里面
[MagicalRecord setupCoreDataStackWithStoreNamed:@"MyDatabase.sqlite"];
解除分配
[MagicalRecord cleanUp];
插入
Person *alex = [Person MR_createEntity]; alex.name = @"Alex"; alex.age = @23;
选择
/ 检索所有的 NSManagedObject 子类
NSArray *people = [Person MR_findAll];
//获取第一条记录
Person *aPerson = [Person MR_findFirst];
//有条件地检索记录并排序
NSArray *people = [Person MR_findByAttribute:@"name" withValue:@"alex" andOrderBy:@"age" ascending:YES];
更新
//更新检索到的实体就像操作它的属性一样简单
aPerson.age = @56;
删除
//删除所有记录
[Person MR_truncateAll];
//删除单条记录,取回后
[alex MR_deleteEntity];
节省
//对于要在磁盘上实际保存/更新/删除的任何实体调用以下方法
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
//再次检查 MagicalRecord 存储库以获得更多保存选项
回答by Arek Holko
I might be mistaken here, but I think that Magical Record isn't prepared for this use case.Here's how I'd do what you want in pure Core Data:
我可能在这里弄错了,但我认为 Magical Record 没有为这个用例做好准备。这是我在纯核心数据中做你想做的事情:
- Create an independent or nested context and keep somewhere (AppDelegate, singleton object, etc.) a reference to it
- Do the insertions, reads, updates and deletions with
performBlock:
andperformBlockAndWait:
Save the context with:
[context performBlock:^{ ZAssert([context save:&error], @"Save failed: %@\n%@", [error localizedDescription], [error userInfo]); }];
- 创建一个独立的或嵌套的上下文并在某处(AppDelegate、单例对象等)保留对它的引用
- 执行插入,读取,更新和删除与
performBlock:
和performBlockAndWait:
使用以下命令保存上下文:
[context performBlock:^{ ZAssert([context save:&error], @"Save failed: %@\n%@", [error localizedDescription], [error userInfo]); }];
This seems to be the standard approach to these kind of problems. It's nicely described online, e.g. Common Background Practices - Core Data in the Background.
这似乎是解决此类问题的标准方法。它在网上很好地描述,例如Common Background Practices - Core Data in the Background。