循环优化/ CoreData优化

时间:2014-06-10 06:13:52

标签: ios iphone xcode core-data

有没有办法优化数组中的循环?我在数组[arr]中有10,000个对象,所以循环将继续10k次,我必须在CfgBarCodeMask和CfgBarCodeMaskDetails之间建立关系。大约需要8分钟。如何减少这段时间?

NSArray *arr=[coreDataEngine  fetchObjectWithEntityName:@"CfgBarCodeMask" withPredicate:nil withSortDescriptor:nil error:nil ];
NSString *predicateString = [NSString stringWithFormat:@"barCodeMaskId == $idVar"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];

[arr enumerateObjectsUsingBlock:^(CfgBarCodeMask *barcodeMask, NSUInteger idx, BOOL *stop) 
{                
    NSDictionary *variables = @{ @"idVar" : barcodeMask.id1 };

    NSArray *destinationArray=
        [coreDataEngine fetchObjectWithEntityName:@"CfgBarCodeMaskDetail" 
                                    withPredicate:[predicate predicateWithSubstitutionVariables:variables] 
                               withSortDescriptor:nil error:nil ];

    if ([destinationArray count] >0 ) {
        [barcodeMask addMaskDetails:[NSSet setWithArray:destinationArray]];
    }           
}];

2 个答案:

答案 0 :(得分:1)

您可以使用将循环划分为多个批次。每个批处理大约2000个对象,并使用并发NSManagedObjectContext来并行执行所有修补程序。这是我从另一个数据库迁移600K对象时所做的。

答案 1 :(得分:0)

我认为你应该有这样的东西

// Create concurency managed object context in your core data engine
_managedObject = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObject setPersistentStoreCoordinator:_psCoordinator];
[_managedObject setUndoManager:nil];


// Batch1
NSPredicate *predicate = //create predicate to get object 1-2000
NSArray *arr=[coreDataEngine  fetchObjectWithEntityName:@"CfgBarCodeMask" withPredicate:predicate withSortDescriptor:nil error:nil];
[self processObjects:arr];

// Batch2
predicate = //create predicate to get object 2000-4000
arr=[coreDataEngine  fetchObjectWithEntityName:@"CfgBarCodeMask" withPredicate:predicate withSortDescriptor:nil error:nil];
[self processObjects:arr];

// Batch3
predicate = //create predicate to get object 4000-6000
arr=[coreDataEngine  fetchObjectWithEntityName:@"CfgBarCodeMask" withPredicate:predicate withSortDescriptor:nil error:nil];
[self processObjects:arr];

// Batch4
predicate = //create predicate to get object 6K-8K
arr=[coreDataEngine  fetchObjectWithEntityName:@"CfgBarCodeMask" withPredicate:predicate withSortDescriptor:nil error:nil];
[self processObjects:arr];

// Batch5
predicate = //create predicate to get object 8K-10K
arr=[coreDataEngine  fetchObjectWithEntityName:@"CfgBarCodeMask" withPredicate:predicate withSortDescriptor:nil error:nil];
[self processObjects:arr];


(void)processObjects:(NSArray) objects
{
    [_managedObject performBlock: {
        NSString *predicateString = [NSString stringWithFormat:@"barCodeMaskId == $idVar"];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
        [arr enumerateObjectsUsingBlock:^(CfgBarCodeMask *barcodeMask, NSUInteger idx, BOOL *stop) 
        {                
            NSDictionary *variables = @{ @"idVar" : barcodeMask.id1 };

            NSArray *destinationArray=
                [coreDataEngine fetchObjectWithEntityName:@"CfgBarCodeMaskDetail" 
                                            withPredicate:[predicate predicateWithSubstitutionVariables:variables] 
                                       withSortDescriptor:nil error:nil ];

            if ([destinationArray count] >0 ) {
                [barcodeMask addMaskDetails:[NSSet setWithArray:destinationArray]];
            }           
        }];
        [_managedObject save:nil];
    }];
}