更新大量NSManagedObject

时间:2015-09-04 12:25:09

标签: ios objective-c performance core-data large-data

关于这类问题有很多问题,但我找不到CoreData的任何问题。问题是:我想更新大量的NSManagedObject(您可以考虑重置大量NSManagedObject的属性)。

现在,我能想到的只有:

  
      
  1. 获取所有对象。
  2.   
  3. 使用forin-loop循环遍历所有内容。
  4.   
  5. 在每个块中设置属性。
  6.   

数据可能很大,我也想为此操作编写一个实用程序。所以问题是:

有没有更有效的方法来执行此操作?我不相信使用for-loop是有效的。

奖金问题

另外,我想删除满足条件的所有对象(很可能是布尔标志)。我的解决方案非常简单,如上所述:

  
      
  1. 使用NSPredicate和条件获取所有对象。
  2.   
  3. 遍历所有,forin。
  4.   
  5. 删除其中的每一个。
  6.   

解决问题的同样问题。

真正的问题

真正的问题是,我想设置所有对象的标志(称之为willDelete)= YES。然后从服务器同步,然后更新它们并设置willDelete = NO。在那之后,任何具有willDelete = YES的都将从上下文中删除。

编辑1

我的问题可能有所不同this one。我想先更新属性。我关心的是表演时间,而不是记忆。

编辑2

好的,我设法使用了NSBatchUpdateRequest。但问题是:我得到了nsmergeConflict。不知道如何处理这一进展。无论如何,这是代码:

- (void)resetProductUpdatedStatus
{
        NSBatchUpdateRequest *request = [NSBatchUpdateRequest batchUpdateRequestWithEntityName:NSStringFromClass([Product class])];
        request.propertiesToUpdate = @{@"hasUpdated" : @(NO)};
        request.resultType = NSUpdatedObjectIDsResultType;
        NSBatchUpdateResult *result = (NSBatchUpdateResult *)[[CoreDataUtil managedObjectContext] executeRequest:request error:nil];
        [result.result enumerateObjectsUsingBlock:^(NSManagedObjectID *objId, NSUInteger idx, BOOL *stop) {
            NSManagedObject *obj = [[CoreDataUtil managedObjectContext] objectWithID:objId];
            if (!obj.isFault) {
                [[CoreDataUtil managedObjectContext] refreshObject:obj mergeChanges:YES];
            }
        }];
}

这将设置所有hasUpdated = NO。接下来,我将执行同步进度。从同步中捕获的所有产品都将更新hasUpdated = YES。接下来执行删除:

- (void)updateProductActiveStatus
{
        NSBatchUpdateRequest *request = [NSBatchUpdateRequest batchUpdateRequestWithEntityName:NSStringFromClass([Product class])];
        request.predicate = [NSPredicate predicateWithFormat:@"hasUpdated = NO"];
        request.propertiesToUpdate = @{@"isActive" : @(NO)};
        request.resultType = NSUpdatedObjectIDsResultType;
        [[CoreDataUtil managedObjectContext] executeRequest:request error:nil];
}

如您所见,我已在更新状态中删除了合并。可能,它会导致重置状态中的合并冲突。所以,我想我将不得不修复合并进度。如果你对此有任何想法,我会问这里的人。

1 个答案:

答案 0 :(得分:1)

在这里,您还可以检查徽章更新所花费的时间远远少于正常更新所发生的时间。在batchupdate中,我们不需要从文件本身获取数据。还要检查我的github链接:https://github.com/tapashm42/CoreDataInSwift.git。 我也在处理batchdelete部分。

func batchUpdate(entityName: String,context:NSManagedObjectContext)  {
        let batchUpdateRequest = NSBatchUpdateRequest(entityName: entityName)
        batchUpdateRequest.propertiesToUpdate = ["name":"Tapash Mollick","designation":"Associate IT Consultant"]
        batchUpdateRequest.resultType = .updatedObjectIDsResultType
        do {
            let start = Date().currentTimeMillis
            let batchUpdateResult = try context.execute(batchUpdateRequest) as! NSBatchUpdateResult
            let result = batchUpdateResult.result as! [NSManagedObjectID]
            print("time taken to update\(Date().currentTimeMillis - start)")
            for objectId in result {
                let manageObject = context.object(with: objectId)
                if (!manageObject.isFault) {
                context.stalenessInterval = 0
                context.refresh(manageObject, mergeChanges: true)
                }
            }
        }
        catch{
            fatalError("Unable to batchUpdate")
        }
    }

extension Date{
    var currentTimeMillis: Int64 {
        return Int64(Date().timeIntervalSince1970 * 1000)
    }
}