0

我正在使用 Core Data 为我的应用程序存储一些信息。我有一个包含 8 个实体的 .xcdatamodeld 文件,我将它们提取到不同的视图中。

在其中一个 viewController 中,我调用了其中的三个。像这样:

    AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication]delegate];

managedObjectContext = appDelegate.managedObjectContext;

NSManagedObjectContext *moc = [self managedObjectContext];


NSEntityDescription *entiAll = [NSEntityDescription entityForName:@"AllWeapons" inManagedObjectContext:moc];
NSFetchRequest *frAll = [[NSFetchRequest alloc] init];
[frAll setEntity:entiAll];
NSError *error = nil;
arrAll = [moc executeFetchRequest:frAll error:&error];
displayArray = [[NSMutableArray alloc]initWithArray:arrAll];


NSEntityDescription *entiRange = [NSEntityDescription entityForName:@"WeaponsRanged" inManagedObjectContext:moc];
NSFetchRequest *frRanged = [[NSFetchRequest alloc] init];
[frRanged setEntity:entiRange];
NSError *errorRanged = nil;
arrRange = [moc executeFetchRequest:frRanged error:&errorRanged];
NSLog(@"%i, %i", [arrRange count], [[moc executeFetchRequest:frRanged error:&errorRanged] count]);


NSEntityDescription *entiMelee = [NSEntityDescription entityForName:@"WeaponsMelee" inManagedObjectContext:moc];
NSFetchRequest *frMelee = [[NSFetchRequest alloc] init];
[frMelee setEntity:entiMelee];
NSError *errorMelee = nil;
arrMelee = [moc executeFetchRequest:frMelee error:&errorMelee];
NSLog(@"%i, %i", [arrMelee count], [[moc executeFetchRequest:frMelee error:&errorMelee] count]);

问题是中间那个(填充 arrRange-array 的那个)不起作用..

arrAll 使用所有正确的数据注销,arrMelee 使用所有正确的数据注销(x4 出于某种原因,不知道这是否相关:S),但 arrRange 作为空数组注销。 [arrRange count];给我 0,即使我知道那里有很多数据。我在模拟器上运行了这段代码,找到了 .sqlite 文件,在 Firefox 的 SQLite 管理器中打开它,看到了正确的数据,40 行。

我进入 appDelegate,在必要时填充 CoreData,并看到以 JSON 格式下载数据的方法也成功地将其发送到 sqlite。

在这里,我用来自 json 的数据填充 CoreData:

[self deleteAllObjects:@"WeaponsRanged"];
NSManagedObjectContext *context = [self managedObjectContext];

for(NSDictionary *item in jsonWeaponRanged)
{
    WeaponsRanged *wr = [NSEntityDescription insertNewObjectForEntityForName:@"WeaponsRanged" 
                    inManagedObjectContext:context];
    ///***///
    wr.recoil = [item objectForKey:@"Recoil"];
    ///***///

     NSError *error;
    if(![context save:&error])
        NSLog(@"%@", [error localizedDescription]);
}

如果我在这里,NSLog(@"%@ - %@", wr.recoil, [item objectForKey:@"Recoil"]);我会得到正确的数据。(两者数据相同)

所以。正确的数据显然在核心中。但是我的 NSFetchRequest 或其他东西失败了。我在 Objective-C 上很菜鸟,所以这可能是我糟糕的代码语法再次引人注目。我意识到我应该再次使用东西等,而不是一直创建新对象。但是 cmon,这是我的第一个应用程序。如果这确实是问题,我可能会学习。但我被困住了。

有时我得到数据,有时我没有。有点奇怪。我重新启动了该应用程序,并从中获取了数据,但现在我没有……我还没有找到模式……

任何人?还是有另一种方式从实体请求数据?

4

2 回答 2

2

我有一些建议,太大了,无法评论。

1) 在创建 WeaponsRanged 之后,尝试读回它们:

for(NSDictionary *item in jsonWeaponRanged)
{
    WeaponsRanged *wr = [NSEntityDescription insertNewObjectForEntityForName:@"WeaponsRanged" 
                    inManagedObjectContext:context];
    NSLog(@"IS WR Realized? %@", wr ? @"YES" : @"NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO WR");
    ///***///
    wr.recoil = [item objectForKey:@"Recoil"];
    ///***///

     NSError *error;
    if(![context save:&error])
        NSLog(@"%@", [error localizedDescription]);
}

// Now lets see if we can retrieve them:
{
    NSEntityDescription *entiRange = [NSEntityDescription entityForName:@"WeaponsRanged" inManagedObjectContext:context];
    NSFetchRequest *frRanged = [[NSFetchRequest alloc] init];
    [frRanged setEntity:entiRange];
    NSError *errorRanged = nil;
    arrRange = [context executeFetchRequest:frRanged error:&errorRanged];
    NSLog(@"Wrote %i items, read back %i items", [jsonWeaponRanged count], [arrRange count] );
}

2)在读取WeaponsRanged的viewController中,在mod上的fetch之前添加一个assert:

    NSLog(@"IS moc set? %@", moc ? @"YES" : @"NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO MOC");

编辑:

3) 在您访问 MOC 的任何地方传播语句:

assert([NSThread isMainThread]); 

[如果您在谷歌之前没有使用过断言并阅读该主题。这些是开发人员在潜在问题出现在 gui 或其他地方之前找出潜在问题的强大工具。它们通常被编译出来用于发布/分发版本。]

如果线程不是主线程,这将强制异常,然后让您通过跟踪堆栈跟踪来追踪原因。

于 2012-08-28T23:17:34.707 回答
0

没关系!这是我自己该死的错(又一次..)。

问题出现在我提供的代码之前,事实证明,当问题出现时,数据从未在 .sqlite 文件中。

这就是我所拥有的:

我通过 json-request 从互联网收集数据。我已经告诉该应用程序通过互联网检查数据的“版本”,如果数据已过时,则重新下载。

首先,我下载所有数据,然后将它们添加到 Core Data 中自己的实体中。下载后,我清除下载数据的当前Core Data实体。所以在每个 add-method 的顶部,它说 ie [self deleteAllObjectsOfEntity:@"WeaponsRanged"];,我的整个问题是,在addMelee-method 中,它还说[self deleteAllObjectsOfEntity:@"WeaponsRanged"];而不是@"WeaponsMelee",因此删除了所有远程武器,然后将近战添加到近战实体中。这也证明了我提到的另一个问题,即 arrMelee 注销了应有的数据的四倍。

The reason it sometimes worked was that the downloading is not happening in any ordered mode. So the addRanged was sometimes called before the addMelee. If ranged comes first, it clears the arrRanged, and fills it up with correct data, and THEN melee comes, and clears it out. When melee was called first, it cleared arrRanged and filled additional data to arrMelee, and THEN ranged comes and tries to clear an empty entity, and then fills it up with correct data.

The solution was obviously to change the entity deleted when adding it, as it was the wrong one.

Sorry.... :)

于 2012-08-29T17:03:41.003 回答