2012-08-28 45 views
0

我正在使用核心数据来存储我的应用程序的一些信息。 我有一个包含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。

这里我填的是CoreData从JSON数据:

[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

您是否从网络上获取JSON数据?如果是这样,你可以显示你的加载例程的代码。 –

+0

嗯..我不认为这与它有任何关系..正如我所说的,数据总是在coredata中,但不会在查询时返回。我已经在所有这些方法中使用了相同的方法,并且我已经证明了.sqlite通过在FireFox中的SQLite管理器中打开它来包含数据。 – Sti

+0

你可以遍历数组并打印'WeaponsRanged'对象吗?例如'for(NSManagedObject * obj in arrRange){NSLog(@“ - >%@”,[obj valueForKey:@“aKey”]); }'。让我知道你看到了什么。 –

回答

0

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

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

这是我有:

我通过JSON请求收集了来自互联网的数据。我告诉应用程序通过互联网检查数据的“版本”,如果数据已过时,请重新下载。

首先,我下载所有数据,然后将它们添加到它们自己的核心数据实体中。下载后,我清除下载数据的当前核心数据实体。因此,在每个添加方法的顶部,它表示,即[self deleteAllObjectsOfEntity:@"WeaponsRanged"];,我的整个问题是在addMelee-方法中,它也说[self deleteAllObjectsOfEntity:@"WeaponsRanged"];而不是@"WeaponsMelee",从而删除所有远程武器,并在后来增加肉搏到近战实体。而且这也证明了我提到的另一个问题,即arrMelee注销的数据量是其导致的数据量的四倍。

它有时工作的原因是下载不会在任何有序模式下发生。所以有时在addMelee之前调用addRanged。如果ranged首先出现,它清除arrRanged,并用正确的数据填充它,然后这个近战来了,并清除它。当首先调用混战时,它会清除arrRanged并将其他数据填充到arrMelee,然后THEN ranged出现并尝试清空空实体,然后用正确的数据填充它。

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

对不起.... :)

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,添加一个断言之前,国防部的获取:

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

编辑:

3)随处可见访问MOC的扩展语句:

assert([NSThread isMainThread]); 

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

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

+0

我可以向你保证数据正确保存,因为我可以预览.sqlite文件并查看数据。但是,现在我无法在模拟器上重现问题。当我启动模拟器时,它显示了一切。当我在设备上启动它时,它有和以前一样的问题。这是完全随机的,早些时候是相反的。我不知道是什么原因造成了这个..断言没有工作..(我真的不知道它是什么,但它没有解决这个问题..) – Sti

+0

断言只是说 - 我“断言”里面是什么真正。所以它不起作用 - 它坠毁了?这意味着moc是零。将断言更改为NSLog,并确保断言内的值不为零。另外,如果你不想尝试我给你的代码,既然你知道sql是正确的,那么我想你可以自己修复它。它不仅仅是我 - 其他人正在阅读。您告诉我们,SQL看起来不错,但没有解决基本问题 - Core Data显然现在正在为您工作。为了纪录,它现在为全世界数百万人工作。 –

+0

不,它没有崩溃。没有任何崩溃,我只是没有从请求中获得任何信息。 moc已设置。正如你所看到的,我总是对这三个请求使用相同的moc。也许这是问题?但是,这并不能解释它有时是如何工作的。对我而言,它似乎是一种窃听。就好像“SELECT * FROM Table”的返回是空的。它仍然作为数组返回,但是是一个空数组。我不知道它为什么有时是空的..现在我无法重现这个问题..而且我没有做任何修复它。似乎是随机的。我不想让它在发布后发生.. – Sti