4

我在现有的 iPhone 项目中实施核心数据时遇到了一些麻烦。首先我想给你一个更详细的看法:

  • 我的一些类相互嵌套:“Game”类有一个带有“Player”类对象的 NSArray,“Player”类有一个带有“Item”类对象的 NSArray。

  • 我想做的是保存我的“uppest”类“游戏”的一个实例(例如,当离开我的应用程序时)。

我尝试了一些关于Core Data的教程,但仍然有一些问题:

  1. 我是否必须为我的每个班级或仅为“游戏”创建一个实体?
  2. 如果我必须为每个人都这样做:我想我必须在我的类之间创建所有关系,但是:如何创建关系,例如“游戏”和“玩家”之间的关系(请提醒:我在一个 NSArray 中拥有许多玩家)..
  3. 改变我现有的项目怎么样?我已经做的是将缺少的方法复制到我的 AppDelegate 中。但是我将如何处理我的课程,尤其是使用 Getter/Setter 方法?只需在实现中将“@synthesize”更改为“@dynamic”?

我希望在我的黑暗中有一些光明;)

非常感谢现在

Mac1988

4

2 回答 2

2

我建议在 xcode 中设置您的数据库模型,然后当您完成此操作时...选择实体并从菜单文件 > 新文件中进行选择。然后从“Cocoa touch 类”中选择“Managed Object Class”。在“下一步”选择保存文件的位置后,下一步 XCode 会询问您应该为文件生成哪些实体。

完成后,您可以将所需的功能实现到您的委托中。我的建议是保留现有的东西并使用核心数据类作为自己的。只需从现有的类/数组中提取您需要的数据,然后根据需要将它们放入数据库中。检索时,反过来......从数据库中获取它们并将它们添加到您的函数/类中。

我的一个项目的示例:

.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. 您已经在问题中得到了答案:建立一对多的关系。例如,对于 Game 的玩家关系,在数据模型编辑器中单击“To-many relationship”复选框。

  3. 你会希望你的数据类(Game、Player、Item)继承自 NSManagedObject。您可能希望删除与您在 Core Data 中添加的属性相对应的所有实例变量。对于多对多关系(玩家、物品),您肯定希望摆脱您正在使用的 NSArray 成员变量。相反,像你说的那样为玩家和物品属性创建@dynamic 访问器。请注意,您希望对玩家和物品使用 NSSet 而不是 NSArray。

例如,您的 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 guide的Using Managed Objects部分有很多很好的细节,但基本上要将 Player 添加到 Game 实例,你会这样做

[game addPlayerObject:newPlayer];

要实际创建新播放器,您可以执行以下操作:

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