我正在使用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,这是我的第一个应用程序..如果这实际上是问题,我可能会学习。但是我被卡住了。
有时我得到数据,有时候我不知道。这很奇怪。我重新启动了应用程序,并从中获取了数据,现在我还没有......我还没有找到一个模式..
任何? 或者是否有其他方式从实体请求数据?
答案 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中,然后测试范围来尝试清空一个空实体,然后用正确的数据填充它。
解决方案显然是在添加实体时更改已删除的实体,因为它是错误的。
抱歉......:)