2
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

4 回答 4

2

有一种记录在案的情况可以给你这种行为。从NSManagedObjectContext文档:

NSManagedObjectContext 已删除对象

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

会不会是你的情况?

于 2013-12-01T10:16:07.007 回答
1

NSManagedObjectContext.hasChangesYES即使您这样做,也会转:

managedObject.someAttribute = managedObject.someAttribute;
于 2015-09-02T17:39:14.923 回答
0

我发现更改属性然后将其更改回其上次保存的值会使 NSManagedObject 变脏。要么这是预期的行为,要么我在此过程中做错了什么。我最终检查了对我有用的 [changedValues 计数],但是您必须考虑自己检查任何瞬态属性,因为它们不会出现在“changedValues”中并且会使您的 NSManagedObject 变脏。

于 2014-06-26T12:02:27.680 回答
0

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

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

(自己就是你的 NSManagedObject)

于 2014-05-12T18:23:50.637 回答