应用程序冻结30-40秒

时间:2015-04-13 06:34:51

标签: ios core-data

我被阻止的UI甚至用于保存coredata背景的父子方法。应用程序冻结30-40秒。我试过GCD但它仍然卡住了。有没有办法删除它?

  **appdelegate**
  - (NSManagedObjectContext *)managedObjectContext
 {


if (_managedObjectContext != nil) {
    return _managedObjectContext;
}


NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
    //        _managedObjectContext = [[NSManagedObjectContext alloc] init];
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}

在保存到DB之前,我曾经调用另一个保存到字典的函数。

   -(void)updateSolicitationWithSyncDetails:(NSDictionary *)inDictionary
  {


NSLog(@"updateSolicitationWithSyncDetails CALLED");

//NSDictionary *loDIct = [inDictionary objectForKey:@"body"];
NSMutableDictionary *paramDict=[NSMutableDictionary dictionaryWithDictionary:inDictionary];
NSString *userEmail=[[NSUserDefaults standardUserDefaults] valueForKey:@"currentUser"];

[paramDict setObject:[NSNumber numberWithBool:NO] forKey:@"isSystemMessage"];
[paramDict setObject:userEmail forKey:@"userEmail"];

if([[inDictionary allKeys] containsObject:@"d-activities"])
{
    NSMutableArray *activityArray=[NSMutableArray arrayWithArray:[inDictionary objectForKey:@"d-activities"]];
    //TODO:Check type
    [self manageActivityArrayWithDetails:activityArray ForType:@"Domain"];
}
if([[inDictionary allKeys] containsObject:@"g-activities"])
{
    NSMutableArray *activityArray=[NSMutableArray arrayWithArray:[inDictionary objectForKey:@"g-activities"]];
    //TODO:Check type
    [self manageActivityArrayWithDetails:activityArray ForType:@"Feedback"];
}
if([[inDictionary allKeys] containsObject:@"p-activities"])
{
    NSMutableArray *activityArray=[NSMutableArray arrayWithArray:[inDictionary objectForKey:@"p-activities"]];
    //TODO:Check type
    [self manageActivityArrayWithDetails:activityArray ForType:@"Private"];
}


if([[inDictionary allKeys] containsObject:@"replies"])
{
    [paramDict setObject:[NSNumber numberWithInteger:[[inDictionary valueForKey:@"replies"] integerValue]] forKey:@"responseCount"];
}
NSDate *threadDate=[NSDate date];

if([[inDictionary allKeys] containsObject:@"created_at"])
{
    double timeInMilliSeconds =[[inDictionary objectForKey:@"created_at"] doubleValue];
    threadDate=[[IXNetworkDataManager sharedNetworkDataManager] retrieveDateFromInterval:timeInMilliSeconds];//Convert timeinterval to date
}
[paramDict setObject:threadDate forKey:@"threadDate"];
[paramDict setObject:[NSDate date] forKey:@"receivedDate"];
if([[inDictionary allKeys] containsObject:@"_id"])
{
    [paramDict setObject:[inDictionary objectForKey:@"_id"] forKey:@"thread"];
    [paramDict setObject:[inDictionary objectForKey:@"_id"] forKey:@"solicitation"];

}
if([[inDictionary allKeys] containsObject:@"owned"])
{
    BOOL isOwned=[[inDictionary valueForKey:@"owned"] boolValue];
    if(isOwned)
    {
        [paramDict setObject:[NSNumber numberWithBool:YES] forKey:@"isRequester"];
    }
    else
    {
        [paramDict setObject:[NSNumber numberWithBool:YES] forKey:@"isProvider"];

    }



}

if([[inDictionary allKeys] containsObject:@"body"])
{

    NSString *message=[[inDictionary objectForKey:@"body"] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];


    BOOL isDuplicate=[[IXDataBaseManager sharedNetworkDataManager] checkForExistenceOfThreadDetailsForSolicitationID:[inDictionary objectForKey:@"_id"]];


    if(!isDuplicate)
    {
       // int randomIndex=[[IXNetworkDataManager sharedNetworkDataManager] getIndexForColorImageForTab:@"OUT"];
        [paramDict setObject:message forKey:@"threadDescription"];

        //[paramDict setObject:[NSNumber numberWithInt:randomIndex] forKey:@"colorCode"];
        [[IXDataBaseManager sharedNetworkDataManager] insertToThreadEntityWithData:paramDict];
    }
    else
    {
        [paramDict setObject:message forKey:@"messageDescription"];
        ThreadInfo *threadInfo=[[IXDataBaseManager sharedNetworkDataManager] retrieveSolicitationInfoForThreadID:[inDictionary objectForKey:@"_id"]];
        [paramDict setObject:threadInfo.threadID forKey:@"thread"];
        [[IXDataBaseManager sharedNetworkDataManager] updateThreadEntityWithSyncDetails:paramDict];
    }

   }



   }

insertToThreadEntityWithData

       AppDelegate *sharedDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [sharedDelegate managedObjectContext];
NSManagedObjectContext *contextforThread = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

contextforThread.parentContext = context;

[contextforThread performBlock:^{

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"UserInfo"
                                          inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *threadPredicate = [NSPredicate predicateWithFormat:@"userEmail == %@",[inDictionary valueForKey:@"userEmail"]];
[fetchRequest setPredicate:threadPredicate];

NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:nil];

ThreadInfo *threadInfo = [NSEntityDescription
                          insertNewObjectForEntityForName:@"ThreadInfo"
                          inManagedObjectContext:context];

for (UserInfo *info in fetchedObjects)
{

    if([[inDictionary allKeys] containsObject:@"userEmail"])
    {
        if([inDictionary valueForKey:@"userEmail"]!=[NSNull null])
        {
            threadInfo.userEmail=[inDictionary valueForKey:@"userEmail"];
        }
    }

    if([[inDictionary allKeys] containsObject:@"thread"])
    {
        if([inDictionary valueForKey:@"thread"]!=[NSNull null])
        {
            threadInfo.threadID=[inDictionary valueForKey:@"thread"];
        }
    }

          NSError *error;
    if(![contextforThread save:&error]) {
        NSLog(@"Child error : %@",error);

    }

    [context performBlock:^{
        NSError *error;
        if(![context save:&error]) {
            NSLog(@"%@",error);
        }
    }];
  }];

1 个答案:

答案 0 :(得分:0)

在我看来,你犯了许多基本错误。

阻止您的应用UI的错误是您将NSPersistentStoreCoordinator绑定到主线程。您的UI适用于主线程。因此,PSC必须与主UI操作一起使用。

您应该考虑在实例化MOC&时创建两个NSManagedObjectContext。 PSC。

  • 一个基于initWithConcurrencyType:NSMainQueueConcurrencyType
  • 一个基于initWithConcurrencyType:NSPrivateQueueConcurrencyType

使用主队列管理对象上下文(MOC)来处理主线程(到内存)中MOC中数据更改的小而频繁的保存,从而将保存对UI的影响降低到可以忽略不计。

您使用专用队列MOC将数据持久保存在后台线程上的磁盘 - 对UI没有影响。

为了使其有效,您需要:

  • 将您的PSC绑定到您的私人MOC,
  • 使私人MOC成为主要MOC的父母,
  • 将用户更改保留在主MOC中的数据
  • 如有必要,将导入的和/或大型数据集保存在另一个“本地”MOC中,该MOC是主要MOC的子级,并且
  • 编写自定义保存方法。

请参阅我在this SO answer中写的保存栏。

去看看核心数据的主人之一是如何做到的...... Marcus Zarra's entry in the Martiancraft Blog ...我从阅读他2013年的核心数据一书中了解了我对这个主题的所有了解。