0

Core Data を使用して、アプリの情報を保存しています。8 つのエンティティを含む .xcdatamodeld ファイルがあり、それらをさまざまなビューで抽出します。

viewController の 1 つで、そのうちの 3 つを呼び出します。このような:

    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 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、これは私の最初のアプリです..そして、それが実際に問題である場合、私は学ぶかもしれません. しかし、私は立ち往生しています。

データを取得する場合もあれば、取得しない場合もあります。それは奇妙だ。アプリを再起動し、そこからデータを取得しましたが、今はありません.. パターンはまだ見つかりません..

誰?または、エンティティからデータを要求する別の方法はありますか?

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のフェッチの前にアサートを追加します。

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

編集:

3)MOCにアクセスするすべての場所にステートメントを広げます。

assert([NSThread isMainThread]); 

[グーグルの前にassertsを使用したことがなく、トピックについて読んだことがない場合。これらは、開発者がGUIまたは他の場所に現れる前に潜在的な問題を見つけるための強力なツールです。それらは通常、リリース/配布ビルド用にコンパイルされます。]

これにより、スレッドがメインスレッドでない場合に例外が強制され、スタックトレースをたどって理由を追跡できるようになります。

于 2012-08-28T23:17:34.707 に答える
0

どうでも!それは私自身の気のせいでした(またしても..)。

私が提示したコードの前に問題が発生し、問題が発生したときにデータが .sqlite ファイルに含まれていなかったことが判明しました。

これは私が持っていたものです:

json-request を介してインターネットからデータを収集しました。インターネット経由でデータの「バージョン」を確認し、データが古い場合は再ダウンロードするようにアプリに指示しました。

まず、すべてのデータをダウンロードしてから、Core Data 内の独自のエンティティに追加します。ダウンロード後、ダウンロードしたデータの現在の Core Data エンティティをクリアします。したがって、各 add-method の上部に、つまり[self deleteAllObjectsOfEntity:@"WeaponsRanged"];、私の全体の問題は、addMelee-method では、[self deleteAllObjectsOfEntity:@"WeaponsRanged"];代わりに も言い@"WeaponsMelee"、すべての遠隔武器を削除し、後で近接エンティティに近接攻撃を追加することでした。また、これは、arrMelee が本来の 4 倍のデータをログアウトするという、私が言及したもう 1 つの問題がこれによって引き起こされたことを証明しています。

時々機能する理由は、ダウンロードがどの順序モードでも行われていないためです。そのため、addRangedが の前に呼び出されることもありましたaddMelee。範囲が最初に来る場合、arrRanged をクリアし、正しいデータで埋めてから、近接攻撃が来て、それをクリアします。melee が最初に呼び出されたとき、arrRanged をクリアして arrMelee に追加データを入力し、次に ranged が来て空のエンティティをクリアしようとし、正しいデータで埋めました。

解決策は明らかに、追加時に削除されたエンティティを変更することでした。これは間違ったものだったからです。

ごめん.... :)

于 2012-08-29T17:03:41.003 に答える