1

私は Apple Developer ガイドとチュートリアルを読み、Core Data に関する 2 冊の iPhone の本を読みました。

私は物事の「値オブジェクト」/「エンティティ」側を処理し、それらを Web サービスなどに送信することに慣れています。しかし、iPhone ではすべてを自分で処理できます… 残酷な世界です :)

、およびApple Developer サイトの例ではLocations、「計算」できる方法で答えが得られません。ここの誰かが私を啓発してくれることを願っています。TaggedLocationsPhotoLocations

データモデル GUI を使用してモデルをセットアップしました。2 つのエンティティ、PersonおよびDream. 文字列属性と 1 対多の関係 Personがあります。文字列属性と 1 対 1 の関係があります。personNamedreamsDreamsdescriptionperson

tableView私は簡単なアプリをセットアップしています。最初のビューは人のリストで、2 番目のビューは彼らの夢のリストです。

これは私が人をに追加する方法ですmodelObjectContext

Person *newPerson = (Person *)[NSEntityDescription
    insertNewObjectForEntityForName:@"Person" 
    inManagedObjectContext:managedObjectContext];
[newPerson setPersonName:@"Ben Hur"];

OK、次にコンテキストに新しい夢を追加します。

Dream *newDream = (Dream *)[NSEntityDescription
    insertNewObjectForEntityForName:@"Dream"
    inManagedObjectContext:managedObjectContext];
[newDream setDescription:@"I had a nightmare"];

私は今、このような人に夢を追加します:

[newPerson addDreamObject:newDream];

Personここでは、クラスで xcode がさまざまなメソッド/アクセサーを生成したため、少しぼんやりしています。

@class Dream;

@interface Person :  NSManagedObject  
{
}

@property (nonatomic, retain) NSString * personName;
@property (nonatomic, retain) NSSet* dream;

@end


@interface Person (CoreDataGeneratedAccessors)
- (void)addDreamObject:(Dream *)value;
- (void)removeDreamObject:(Dream *)value;
- (void)addDream:(NSSet *)value;
- (void)removeDream:(NSSet *)value;

@end

他の状況では、実際の保存、取得、データを処理する必要はありませんでした。私はエンティティ/値オブジェクトを作成し、夢を保存するためにpersonそれを与えました。Arrayしかし、これはコアデータで可能な属性タイプではなく、それを行う方法でもありません.

では、このボイラープレート コードはどのように機能するのでしょうか。を使って夢いっぱいaddDream送っていいのかな?または、コアデータを信頼してこれをインスタンス化し、タイプのエンティティオブジェクトを送信するNSSetだけを使用できますか?addDreamObjectPersonDreams

また、xcode のボイラープレート コードを使用してコンテキストを保存します。ここで、ビューをこの人物、より正確には彼の名前で更新したいと思います。

メソッドでは、次のcellForRowAtIndexPathように指定します。

NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [[managedObject valueForKey:@"personName"] description];

再びすべてがうまくいき、名前がリストに表示されます。

オブジェクトをパラメーターとしてDreamViewController受け取るように設定しました。Person

Person *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
dreamView.selectedPerson = selectedObject;

viewController次に、 をスタックにプッシュし、に入りますDreamView。ここでは、私が「一緒に送った」人に関連する夢を見ることができないようです。

これは私がDreamViewController'sviewDidLoadメソッドで試していることです (オブジェクトselectedPersonを渡すために使用するアクセサーです):Person

- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"One Person";

NSManagedObjectContext *context = selectedPerson.managedObjectContext;

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Dream"
                                          inManagedObjectContext:context];
[fetchRequest setEntity:entity];

NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
    // Handle the error.
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    exit(-1);  // Fail
}

NSMutableArray *mutableArray = [fetchedObjects mutableCopy];
self.dreamArray = mutableArray;
NSLog(@"the length of dreamArray: %i",[self.dreamArray count] );

Dream *d = [dreamArray objectAtIndex:0];
NSLog(@"The Dream object says: %@", [d description]);
[mutableArray release];

[fetchRequest release];
}

私は本当にこれを理解することができないようです.Objective Cでの私の現在の経験では、Appleのドキュメントの行間から「ベストプラクティス」の本質をつかむことはできません.

4

1 に答える 1

3

まず、モデルで犯した間違いを修正する必要があります。夢のエンティティに「説明」という属性を含めることはできません。「説明」はメソッドの名前であるため、これは禁止されています。

Apple のドキュメント (Core Data プログラミング ガイド) から:

プロパティ名は、NSObject または NSManagedObject のパラメータのないメソッド名と同じにすることはできません。たとえば、プロパティに「説明」という名前を付けることはできません (NSPropertyDescription を参照)。

addDreamObject: と addDream: の違いは、前者は対多関係に Dream オブジェクトを挿入するために使用され、後者は対多関係のコンテキストをワンショットで挿入または置換するために使用されることです。

使用しないでください

cell.textLabel.text = [[managedObject valueForKey:@"personName"] description];

単純に使用する必要があります

cell.textLabel.text = [managedObject valueForKey:@"personName"];

本人に関係する夢については、追加のフェッチリクエストは必要ありません。person オブジェクトを取得したら、次のようにその人の夢にアクセスするだけです。

for(Dream *dream in person.dreams){
   // process your Dream object
}

最後に、マネージド オブジェクト コンテキストをインスタンス変数として DreamViewController に明示的に渡さない理由が明確ではありません。これは一般的な方法であり、Apple のサンプル コードにも示されています。別のエラーがチェック中です

if (fetchedObjects == nil)

クエリで実際にオブジェクトが見つからなかった場合に nil を返すことは正当であるためです。代わりに、NSError オブジェクトが nil でないかどうかを確認する必要があります (フェッチ要求を実行する前に、nil に初期化する必要があります)。

if(error)

ステートメント

NSLog(@"The Dream object says: %@", [d description]);

私の回答の冒頭で説明したように、アプリケーションがクラッシュすることさえあります。

于 2009-10-18T08:29:15.587 に答える