4

Core Data を既存の iPhone プロジェクトに実装する際に問題が発生しました。最初に、より詳細なビューを提供したいと思います。

  • 一部のクラスは互いに入れ子になっています。クラス「Game」にはクラス「Player」のオブジェクトを持つ NSArray があり、クラス「Player」にはクラス「Item」のオブジェクトを持つ NSArray があります。

  • 私がやりたいのは、「uppest」クラス「Game」のインスタンスを保存することです(たとえば、アプリを終了するとき)。

Core Data に関するいくつかのチュートリアルを試してみましたが、まだいくつかの質問があります。

  1. クラスごとにエンティティを作成する必要がありますか?それとも「ゲーム」だけにエンティティを作成する必要がありますか?
  2. それぞれに対してそれをしなければならない場合:クラス間のすべての関係を作成する必要があると思いますが、たとえば「ゲーム」と「プレーヤー」の間の関係を作成する方法(思い出してください:私は1つのNSArrayに多くのプレーヤーを保持しています)..
  3. 既存のプロジェクトを変更するのはどうですか? 私がすでに行ったことは、不足しているメソッドを AppDelegate にコピーすることです。しかし、クラス、特に Getter/Setter メソッドをどうする必要がありますか? 実装で「@synthesize」を「@dynamic」に変更するだけですか?

私は私の暗闇の中でいくつかの光を願っています;)

今までありがとう

Mac1988

4

2 に答える 2

2

私がお勧めするのは、xcode でデータベース モデルをセットアップすることです。それが完了したら、エンティティを選択し、メニューから [ファイル] > [新しいファイル] を選択します。次に、「Cocoa touch クラス」から「Managed Object Class」を選択します。「次へ」の後、ファイルを保存する場所を選択します。次のステップで、XCode はどのエンティティをファイルに生成するかを尋ねます。

それが終わったら、デリゲートなどに必要な機能を実装できます。既存のものをそのままにして、コア データ クラスを独自のものとして使用することをお勧めします。既存のクラス/配列から必要なデータを取得し、必要に応じてデータベースに配置するだけです。取得するときは、逆に... DBから取得して、関数/クラスに追加します。

私のプロジェクトの例:

.h ファイル

@class quicklistSet;

@interface rankedAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
[...]

    NSMutableArray *_searchHistory;
    NSMutableArray *_quickList;
}

[...]

@property (nonatomic, retain) NSMutableArray *_searchHistory;
@property (nonatomic, retain) NSMutableArray *_quickList;

/* Quicklist functions */
- (void)addToQuicklist:(quicklistSet *)theQuicklistSet;
- (BOOL)checkIfQuicklistExists:(quicklistSet*)theQuicklistSet;
- (NSMutableArray *)getQuicklists;
- (void)deleteQuicklist:(NSNumber*)theAppId;


@end

.m ファイル

#import "quicklistSet.h"
#import "quicklist.h"

@implementation rankedAppDelegate

@synthesize window;
@synthesize tabBarController;
@synthesize _searchHistory, _quickList;

[...]

/* Quicklist functions */
- (void)addToQuicklist:(quicklistSet *)theQuicklistSet
{
    BOOL exists = [self checkIfQuicklistExists:theQuicklistSet];

    if(!exists)
    {
        quicklist *theQuicklist = (quicklist *)[NSEntityDescription insertNewObjectForEntityForName:@"quicklist"
                                                                                      inManagedObjectContext:self.managedObjectContext];

        [theQuicklist setAppName:[theQuicklistSet _appName]];
        [theQuicklist setAppId:[theQuicklistSet _appId]];
        [theQuicklist setAppImage:[theQuicklistSet _appImage]];
        [theQuicklist setCountryId:[theQuicklistSet _countryId]];
        [theQuicklist setCategoryId:[theQuicklistSet _categoryId]];
        [theQuicklist setLastCheck:[theQuicklistSet _lastCheck]];
        [theQuicklist setLastRank:[theQuicklistSet _lastRank]];

        [_quickList addObject:theQuicklist];

        [self saveAction];
    }
    else {
        NSLog(@"Existing quicklistSet: %@", [theQuicklistSet _appName]);
    }
}

- (BOOL)checkIfQuicklistExists:(quicklistSet*)theQuicklistSet
{
    // Get the categories
    NSMutableArray *quicklistArray = [self getQuicklists];

    BOOL exists = NO;

    for(quicklist *dbQuicklist in quicklistArray)
    {
        if([[dbQuicklist appId] isEqualToNumber:[theQuicklistSet _appId]])
        {
            exists = YES;
            continue;
        }
    }

    return exists;
}

- (NSMutableArray *)getQuicklists
{
    if(_quickList == NULL)
    {
        NSLog(@"Array is null");

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

        NSEntityDescription *entity = [NSEntityDescription entityForName:@"quicklist" 
                                                  inManagedObjectContext:self.managedObjectContext];
        [fetchRequest setEntity:entity];

        NSError *error;
        NSArray *items = [[self.managedObjectContext
                           executeFetchRequest:fetchRequest error:&error] retain];

        NSMutableArray *returnArray = [[[NSMutableArray alloc] initWithArray:items] retain];

        _quickList = returnArray;

        [fetchRequest release];
    }
    else {
        NSLog(@"Not null. Count: %d", [_quickList count]);
    }

    return _quickList;
}

- (void)deleteQuicklist:(NSNumber*)theAppId
{
    NSLog(@"Delete row");

    // Create a new managed object context for the new book -- set its persistent store coordinator to the same as that from the fetched results controller's context.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"quicklist" 
                                              inManagedObjectContext:self.managedObjectContext];

    [fetchRequest setEntity:entity];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"appId=%@",theAppId];
    [fetchRequest setPredicate:predicate];

    NSError *error;
    NSArray *items = [self.managedObjectContext
                      executeFetchRequest:fetchRequest error:&error];
    [fetchRequest release];

    if([items count] > 0)
    {
        NSManagedObject *eventToDelete = [items objectAtIndex:0];
        [self.managedObjectContext deleteObject:eventToDelete];

        [self saveAction];
    }
}
/* END Quciklist functions */

[...]

@end

編集:quicklistSet は私の既存のクラスで、quicklist は私の coredata クラスです。

于 2009-12-01T12:42:13.317 に答える
1
  1. はい、あなたが言及したすべてのクラスのエンティティを作成したいと考えています。

  2. これに対する答えは、あなたの質問で既に得ています: 1 対多の関係を作成します。たとえば、ゲームのプレーヤー関係の場合、データ モデル エディターで [対多関係] チェックボックスをクリックします。

  3. データ クラス (Game、Player、Item) を NSManagedObject から継承する必要があります。Core Data に追加した属性に対応するすべてのインスタンス変数を削除したくなるでしょう。対多の関係 (プレイヤー、アイテム) の場合、使用していた NSArray メンバー変数を確実に削除する必要があります。代わりに、あなたが言ったようにして、プレーヤーとアイテムのプロパティの @dynamic アクセサーを作成してください。プレイヤーとアイテムには NSArray の代わりに NSSet を使用することに注意してください。

たとえば、Game クラスのヘッダーは次のようになります。

@interface Game : NSManagedObject {

}

@property(nonatomic, retain) NSSet *players
@property(nonatomic, retain) NSString *someOtherProperty;
@property(nonatomic, retain) NSNumber *yetAnotherProperty;

@end

そして、実装ファイルは次のようになります。

#import "Game.h"

@implementation Game

@dynamic players, someOtherProperty, yetAnotherProperty;

- (void)awakeFromInsert {
    // do initialization here
}

// other methods go here

@end

また、プレーヤーとアイテムのプロパティを変更するときは注意してください。Core Data Programming ガイドのUsing Managed Objectsセクションには多くの優れた詳細がありますが、基本的に Player を Game インスタンスに追加するには、次のようにします。

[game addPlayerObject:newPlayer];

実際に新しいプレーヤーを作成するには、次のようにします。

NSManagedObject *newPlayer = [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:context];
于 2009-12-06T20:45:50.820 に答える