2012-08-28 82 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