Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用Magic Record将核心数据保存在单独的线程上_Ios_Objective C_Magicalrecord - Fatal编程技术网

Ios 使用Magic Record将核心数据保存在单独的线程上

Ios 使用Magic Record将核心数据保存在单独的线程上,ios,objective-c,magicalrecord,Ios,Objective C,Magicalrecord,我正在使用Magic Record帮助保存核心数据和多线程 我用GCD开始了一个新的线程。在这个新线程中,我检查实体是否存在;如果没有,我想创建一个新的并保存它 如果在非主线程上调用主线程,则saveUsingCurrentThreadContextWithBlock^(NSManagedObjectContext*localContext){}是否将返回主线程进行保存 或者我应该将上下文传递给新线程吗 编辑: 在主线程上,我创建一个MBProgress指示器并创建一个新线程: MBProgre

我正在使用Magic Record帮助保存核心数据和多线程

我用GCD开始了一个新的线程。在这个新线程中,我检查实体是否存在;如果没有,我想创建一个新的并保存它

如果在非主线程上调用主线程,则
saveUsingCurrentThreadContextWithBlock^(NSManagedObjectContext*localContext){}
是否将返回主线程进行保存

或者我应该将上下文传递给新线程吗

编辑:

在主线程上,我创建一个MBProgress指示器并创建一个新线程:

MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.mapView animated:YES];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{

    Person *person = [Person MR_findFirstByAttribute:NAME withValue:self.user.username];

    if (person == NULL) {
        NSLog(@"SEPERATE THREAD | person %@ does not exist, creating", self.user.username);
        person = [Person MR_createEntity];
        person.name = self.user.username;
        person.uid = self.user.UID;

        [[NSManagedObjectContext MR_contextForCurrentThread] MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
            [MBProgressHUD hideHUDForView:self.mapView animated:YES];

            Person *person = [Person MR_findFirstByAttribute:NAME withValue:self.user.username];

            if (person) {
                NSLog(@"COMPLETION BLOCK | person exists: %@", person.name);
            }
        }];
    }
    else {
        NSLog(@"SEPERATE THREAD | person %@ does", self.user.username);

            dispatch_async(dispatch_get_main_queue(), ^{
                [MBProgressHUD hideHUDForView:self.mapView animated:YES];
            });
    }
});
(此保存方法不是持久性,我重新启动应用程序,但找不到Person实体):

2013-03-12 14:25:44.014分离线程|个人标识符不存在,正在创建
2013-03-12 14:25:44.014分离线程|线程:{name=(null),num=4}
2013-03-12 14:25:44.015-[NSManagedObjectContext(MagicalSaves)MR_saveWithOptions:completion:(0x840ec30)→ 在***后台线程上保存***
2013-03-12 14:25:44.015-[NSManagedObjectContext(MagicalSaves)MR_saveWithOptions:completion:(0x840ec30)→ 拯救父母?0
2013-03-12 14:25:44.015-[NSManagedObjectContext(MagicalSaves)MR_saveWithOptions:completion:(0x840ec30)→ 同步保存?0
2013-03-12 14:25:44.016-[NSManagedObjectContext(MagicalRecord)MR_contextWillSave:(0x840ec30)未命名的上下文即将保存。获取新插入对象的永久ID 1
2013-03-12 14:25:44.132-[NSManagedObjectContext(MagicalSaves)MR_saveWithOptions:completion:][u block_invoke21(0x840ec30)→ 已完成保存:在***后台线程上***
2013-03-12 14:25:44.134完成块|线程:{name=(null),num=1}
2013-03-12 14:25:44.134完井区块|存在人员:iDealer

是,完成块在主线程中执行。例如:

NSOperationQueue *newQueue = [[NSOperationQueue alloc] init];
[newQueue addOperationWithBlock:^{
    [MagicalRecord saveUsingCurrentThreadContextWithBlock:^(NSManagedObjectContext *localContext) {
        // save something
    } completion:^(BOOL success, NSError *error) {
        // this will execute in the main thread
    }];
}];

在MagicalRecord的当前版本中,是,完成块将返回到主线程。但是,这里的方法是不正确的。现在,save方法有了更明确的变体:

saveOnlySelf:completion:
saveToPersistentStore:completion:
请查看当前版本中的这些方法。作为提醒,请确保您只使用提供给您的localContext中的托管对象。该工作块可以在任何线程/队列中运行,在这种情况下,您仍然希望对核心数据使用正确的线程管理规则。

好的,我让它工作了:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    Person *person = [Person MR_findFirstByAttribute:NAME withValue:self.user.username];

    if (person == NULL) {
            [MagicalRecord saveUsingCurrentThreadContextWithBlock:^(NSManagedObjectContext *localContext){
                Person *localPerson = [Person MR_createInContext:localContext];
                localPerson.name = self.user.username;

            } completion:^(BOOL success, NSError *error){
                [MBProgressHUD hideHUDForView:self.mapView animated:YES];
            }];
    }
    else {
        dispatch_async(dispatch_get_main_queue(), ^{
            [MBProgressHUD hideHUDForView:self.mapView animated:YES];
        });
    }
});
这样既有效又节省。我不确定卡萨德莫拉用这种方法的意思是不正确的。我无法确定使用此方法与使用
saveOnlySelf:completion:
方法之间的区别

似乎我永远无法使用
saveOnlySelf
将上下文保存到持久存储中。如果我用问题中的代码创建它,它将被放置在上下文中。如果我搜索Person实体,我可以找到它。但一旦我终止应用程序并重新启动,那个人实体就不存在了。感觉就像我正在将线程上下文保存或合并到主/默认上下文,但没有保存该上下文

编辑:

在对MR进行更多的操作之后,如果在非主线程中使用任何
saveOnlySelf
方法,它会将本地上下文合并到默认上下文中,但不会将其保存到持久存储中。如果在完成后检查默认上下文,则新实体确实存在。但是一旦你终止了应用程序并重新运行它,它就不在那里了


要合并上下文并保存到存储,需要调用
savetopersistentstore和wait
type方法之一

呃,这只是保存到主上下文吗??它是保存主上下文还是我仍然需要手动保存?这里有两种保存默认上下文的方法:1)子上下文是默认上下文的子上下文,2)子上下文是默认上下文的远程子上下文,调用了saveToPersistentStore:completion:“saveUsingCurrentThreadContextWithBlock”中的代码正在后台线程中执行(根据MR文档)-为什么在这里使用GCD?
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    Person *person = [Person MR_findFirstByAttribute:NAME withValue:self.user.username];

    if (person == NULL) {
            [MagicalRecord saveUsingCurrentThreadContextWithBlock:^(NSManagedObjectContext *localContext){
                Person *localPerson = [Person MR_createInContext:localContext];
                localPerson.name = self.user.username;

            } completion:^(BOOL success, NSError *error){
                [MBProgressHUD hideHUDForView:self.mapView animated:YES];
            }];
    }
    else {
        dispatch_async(dispatch_get_main_queue(), ^{
            [MBProgressHUD hideHUDForView:self.mapView animated:YES];
        });
    }
});