没有从Core Data获取数据

时间:2012-08-28 18:50:01

标签: objective-c ios cocoa-touch core-data nsfetchrequest

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

在其中一个viewControllers中,我调用其中三个。像这样:

    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数组的那个)不起作用..

arrAll使用所有正确的数据注销,arrMelee使用所有正确的数据注销(x4由于某种原因,不知道这是否相关:S),但是arrRange注销为空数组。 [arrRange count];给了我0,即使我知道那里有很多数据。 我在模拟器上运行了这段代码,找到了.sqlite文件,在Firefox的SQLite Manager中打开它,看到了正确的数据,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,这是我的第一个应用程序..如果这实际上是问题,我可能会学习。但是我被卡住了。

有时我得到数据,有时候我不知道。这很奇怪。我重新启动了应用程序,并从中获取了数据,现在我还没有......我还没有找到一个模式..

任何? 或者是否有其他方式从实体请求数据?

2 个答案:

答案 0 :(得分: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)在viewController中读取WeaponsRanged,在mod上获取之前添加一个断言:

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

编辑:

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

assert([NSThread isMainThread]); 

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

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

答案 1 :(得分:0)

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

在我提交的代码之前出现了问题,并且当问题出现时,数据从未出现在.sqlite文件中。

这就是我所拥有的:

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

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

它有时工作的原因是下载不是以任何有序模式进行的。因此有时在addRanged之前调用addMelee。如果ranged是第一个,它会清除arrRanged,并用正确的数据填充它,然后混战来了,并清除它。当首先调用近战时,它会清除arrRanged并将其他数据填充到arrMelee中,然后测试范围来尝试清空一个空实体,然后用正确的数据填充它。

解决方案显然是在添加实体时更改已删除的实体,因为它是错误的。

抱歉......:)