2

我有一个应用程序,在第一次运行时,它从后端服务(StackMob,但我认为服务的选择不是这里的一个因素)下载一堆数据,将其缓存到 plist 文件,并从plists 到核心数据存储中。在随后的运行中,它使用相同的类来获取任何新的或更新的数据并将其同步到核心数据存储中。我正在使用 MagicalRecord 而不是 Apple 的核心数据堆栈,并且在 NSOperationQueue 中执行导入/同步。

该队列为 8 个实体中的每一个运行一种方法,其中一种方法看起来像这样......

- (void)processAppData
{
    NSString *entityName = kEntityAppData;                                          // customise for entity
    NSString *smidName = kAttribute_appdata_id;                                     // customise for entity
    NSArray *syncData = [MFGlobals cachedDataForName:entityName];
    [[NSFileManager defaultManager] removeItemAtPath:[MFGlobals cachePathForDownloadNamed:entityName]
                                               error:nil];
    if (!syncData) return;

    NSLog(@"%@ items: %i", entityName, [syncData count]);
    NSNumber *lastUpdated = [MFGlobals lastUpdatedEntityNamed:entityName];
    NSLog(@"Last updated %@: %qu", entityName, [lastUpdated unsignedLongLongValue]);

    for (NSDictionary *item in syncData) {
        AppData *object;                                                            // customise for entity
        NSString *smid = [item objectForKey:smidName];
        NSNumber *lastmoddate = [item objectForKey:kAttribute_lastmoddate];
        NSLog(@"%@ item with ID: %@ lastmoddate: %qu", entityName, smid, [lastmoddate unsignedLongLongValue]);

        object = [self dataItemFromEntity:entityName withID:smid inField:smidName];

        if (!object) {
            // we have to create a new item
            object = [NSEntityDescription insertNewObjectForEntityForName:entityName
                                                   inManagedObjectContext:localContext];
            [object setAppdata_id:smid];                                            // customise for entity
        } else {
            // we have an item that _might_ need updating
            if ([object lastmoddate] >= lastmoddate)
                continue;
        }

        [object setLastmoddate:lastmoddate];
        [object setValue:[item objectForKey:kAttribute_value]];
        NSLog(@"new/updated %@ object: %@", entityName, [object description]);

        [localContext saveNestedContexts];
        NSLog(@"%@ object updated.", entityName);

        if ([lastmoddate compare:lastUpdated] == NSOrderedDescending)
            lastUpdated = lastmoddate;
    }

    [MFGlobals setLastUpdated:lastUpdated forEntityNamed:entityName];
    NSLog(@"New last updated %@: %qu", entityName, [lastUpdated unsignedLongLongValue]);
}

如果我使用[localContext save]而不是[localContext saveNestedContexts]该过程似乎可以正常运行。数据何时以及应该如何出现在我的 UI 中,我可以在我的应用程序中导航,但数据不会持久保存到 sqlite 数据库。

从这里获得灵感 MagicalRecord - saveinBackground 不持久化数据?我切换到使用[localContext saveNestedContexts]& 它现在可以正确处理和保留前 6 个实体的数据。但是,在下一个实体的第一条记录中,它会正确保存该记录,然后我的应用程序进入锁定状态。当我再次运行该应用程序时,该实体的下一条(实际上是第一条新)记录也会发生同样的情况。当我拥有该实体中的所有数据时,下一个(& 最后一个实体)的第一个(& 当前唯一)记录也会发生同样的情况。

我在这里描述的方法与我成功使用 Apple 风格的 Core-Data 代码的方法基本相同,只是我NSManagedObjectContext在上下文中使用了 MagicalRecord 提供的和 MagicalRecord 保存方法。

我也尝试过使用 MagicalRecord saveInBackgroundWithBlock(不使用队列)来执行此操作,但遇到了我所有实体的第一条记录锁定问题。

关于如何使其正常工作的任何线索?

干杯和 TIA,佩德罗

4

0 回答 0