这是否总是正确的,如果managedobjectcontext更改,那么必须删除,更新或添加某些内容?

时间:2013-11-14 11:05:22

标签: objective-c core-data nsmanagedobjectcontext

NSUInteger numberOfChanges = moc.insertedObjects.count + moc.deletedObjects.count+moc.updatedObjects.count;

if (numberOfChanges ==0 )
{
    NSAssert([moc hasChanges]==false,@"[moc hasChanges]==false");
    return;
}

断言失败了。我想知道为什么。所以什么也没插入。什么都没有删除。什么都没有更新。然而[moc hasChanges]是真的吗?这很少发生。但是,它根本不应该发生。

如果有人想看,这是完整的代码。

+(void)commit {

    [BGHPTools breakIfLock];
    NSManagedObjectContext *moc = [self managedObjectContext];

    NSArray * arUpdatedObjects = moc.updatedObjects.allObjects;

    NSArray * arUpdatedObjectsID = [arUpdatedObjects convertByPeformingSelector:@selector(objectID)];
    NSUInteger numberOfChanges = moc.insertedObjects.count + moc.deletedObjects.count+moc.updatedObjects.count;

    if (numberOfChanges ==0 )
    {
        //NSAssert([moc hasChanges]==false,@"[moc hasChanges]==false");
        return;
    }
    if (arUpdatedObjectsID.count) {
        while (false);
    }

    [BGFetchClass vAddObjectIDCachesForArray:moc.insertedObjects.allObjects];
    [BGFetchClass vDeleteObjectsForArray:moc.deletedObjects.allObjects];
    /*if (numberOfChanges ==0 )
    {
        NSAssert([moc hasChanges]==false,@"[moc hasChanges]==false");
        return;
    }*/
    //NSAssert([moc hasChanges],@"[moc hasChanges]==true");
    __block NSError *error;

    __block BOOL saveSuccesfully;

    [moc performBlockAndWait:^{
        @synchronized([BGFetchClass class])
        {
            saveSuccesfully = [moc save:&error];
            if (!saveSuccesfully) {
                CLog(@"Error in Saving %@", error);
            }
            else{
            }
        }
    }];

    if (![NSThread isMainThread]) {
        if (arUpdatedObjectsID.count) { //When we're adding new objects, this won't be called. That is the only time commit is called while we are synching
            [BGHPTools vDoForeGroundAndWait:^{
                NSManagedObjectContext * moc =[BGMDCRManagedObjectContextThreadHandler managedObjectContext];
                for (NSManagedObjectID * moi in arUpdatedObjectsID) {
                    NSManagedObject * mo = [moc existingObjectWithID:moi error:nil];
                    NSAssert(mo!=nil, @"Object can't possibly be nil");
                    [mo turnToFault];
                }
            }];
        }
    }

    NSManagedObjectContext * parentMoc = [self managedObjectContextMainContext]; //Main parent is not nsmainqueueconcurency type. Hence, this is save
    [parentMoc performBlockAndWait:^{
        if (![parentMoc save:&error])
        {
            CLog(@"Error in Saving %@", error);// handle error
        }
    }];
    NSAssert(error==nil, @"Error must be nill");
}

4 个答案:

答案 0 :(得分:2)

有一种记录在案的情况会给你这种行为。 来自NSManagedObjectContext文档:

NSManagedObjectContext deletedObjects

  

讨论
  返回的集合不一定包括已删除的所有对象(使用deleteObject :) - 如果插入和删除了一个对象而没有插入保存操作,则它不包含在集合中。

可能是你的情况吗?

答案 1 :(得分:1)

即使你这样做,

NSManagedObjectContext.hasChanges也会转为YES

managedObject.someAttribute = managedObject.someAttribute;

答案 2 :(得分:0)

NSManagedObject有时会失败。尝试使用:

- (BOOL)hasAnythingChanged {
    return [[[self changedValues] allKeys] count] > 0;
}

(自己是你的NSManagedObject)

答案 3 :(得分:0)

我发现更改属性然后将其更改回上次保存的值会使NSManagedObject变脏。要么就是预期的行为,要么我一路走错了。我最终检查了[changedValues count]对我有用但是你必须考虑自己检查任何瞬态属性,因为它们不会出现在'changedValues'中并且会使你的NSManagedObject变脏。