3

コード:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"A"
                                          inManagedObjectContext:moc];
[fetchRequest setEntity:entity];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"id" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"somePredicate", someObject];
[fetchRequest setPredicate:predicate];

frc = [[NSFetchedResultsController alloc]
       initWithFetchRequest:fetchRequest
       managedObjectContext:moc
       sectionNameKeyPath:@"recency"
       cacheName:@"frc"];
[fetchRequest release];

frc.delegate = self;

NSError *error;
BOOL success = [frc performFetch:&error];
if (!success) {
    NSLog(@"error: %@", error);
}

for (A *a in [frc fetchedObjects]) {        
    [someMutableArray addObject:a.b];
    [someMutableArray addObject:a];
}

データ・モデル:

A と B はエンティティです。A は B に対して必須の対 1 関係を持ちます。B は A に対して逆のオプションの対多関係を持ちます。

上は英語で:

NSFetchedResultsController を初期化して、テーブルビューを強化するデータを取得します。最初のフェッチの後、何らかの処理のためにデータを取っておきます。

さて、後で、私はこれをやろうとします:

id object = [someMutableArray objectAtIndex:someIndex];
NSLog(@"%@", object);

if ([object isMemberOfClass:[B class]]) {
    someVar = object.propertyFromB; // problem
} else if ([object isMemberOfClass:[A class]]) {
    someVar = object.propertyFromA;
}

質問/問題: 「問題」で示される行がクラッシュします。(編集:解決策については以下を参照してください。ただし、それでも説明が必要です。)

上記の NSLog 呼び出しにより、次の結果が得られます。

2010-01-30 14:47:14.433 app[22618:20b] <B: 0xf7f750> (entity: B; id: 0xf7ba70 <x-coredata://B01FEC86-14D6-4973-BFDB-EDE4AFD24FDC/B/p4> ; data: <fault>)
2010-01-30 14:47:14.438 app[22618:20b] <A: 0xf7e360> (entity: A; id: 0xf35820 <x-coredata://B01FEC86-14D6-4973-BFDB-EDE4AFD24FDC/A/p6> ; data: {
    prop1 = value1;
    prop2 = value2;
    ... etc ...
})

つまり、問題のある行によると、オブジェクトがタイプ A の場合、障害が発生しており、メモリで使用できますが、B の場合は障害です。

私の理解では、「問題」行が障害を発生させ、ストアからデータをフェッチする必要がありますが、これは起こっていません。理由を理解し/デバッグしたいと思います。これに willAccessKey/didAccessKey 呼び出しを挿入しようとしました。また、フェッチ要求で setRelationshipKeyPathsForPrefetching:"b" を設定しようとしました。どちらも機能しませんでした。

私の仮説は、NSFetchedRequestController の結果をいくらか悪用しているため、障害のあるエンジンが途中で混乱し、想定されているときに障害をフェッチしないというものです。したがって、適切なタイミングで関連する B オブジェクトをフェッチするために、新しい手動フェッチ リクエストを作成するのが強引な方法だと思います。しかし、より良い方法はありますか?

編集:

問題は、オブジェクト B に私が定義したプロパティ「説明」があったが、それが NSObject の組み込み名と衝突することでした。Xcodeは常に警告を出しましたが、「説明」の内部プロパティ/メソッドは、内部処理ではなく、コンソールなどに文字列をダンプするためにのみ使用されると考えたため、それらを無視しました。

モデルの新しいバージョンを作成し、「説明」の名前を別の名前に変更すると、問題はなくなりました。すべての障害が期待どおりに機能し始めました。

とはいえ、何が起こっているのかわかりません。Core Data は、オブジェクトの「説明」メソッドを使用して内部内省を行っていますか?

4

3 に答える 3

6

コアデータプログラミングガイドより

説明 (デバッグ操作中にこのメソッドがエラーを発生させると、結果が予測不能になる可能性があります) および initWithEntity:insertIntoManagedObjectContext: を上書きすることはお勧めできません。通常、valueForKey: や setValue:forKeyPath: などのキーと値のコーディング メソッドをオーバーライドしないでください。

-descriptionオブジェクトの文字列表現を返す NSObject のメソッドです。行NSLog(@"%@", object)-descriptionは、コンソールに表示される文字列を取得するために使用されます。キーと値のコーディングは、メソッドを使用して description 属性のプロパティを取得することになります。これにより、Core Data に多くの混乱が生じます。

プログラミングガイドは、「落胆」と言っているときは寛大です。彼らは本当に「うん、それはあなたのものを壊すだろう」という意味です.

そのリンクには、オーバーライドするとあなたのものを壊す他のメソッドの良いリストもあります。

于 2010-01-31T05:35:38.293 に答える
0

description は予約語として扱う必要があります。それがあなたが抱えている問題です。description というプロパティを取得しようとすると、警告が表示されるはずです。

于 2010-01-31T07:19:08.213 に答える
0

-(NSString *)debugDescriptionカスタムの説明については、NSObject プロトコルからオーバーライドできます。Appleのドキュメントから:

NSObject は、description メソッドを呼び出してこのメ​​ソッドを実装します。したがって、デフォルトでは、オブジェクトのデバッグ記述はその記述と同じです。ただし、これらを切り離したい場合は、debugDescription をオーバーライドできます。

于 2013-01-15T18:27:03.363 に答える