将核心数据实施到现有的iPhone项目

时间:2009-12-01 07:37:06

标签: iphone core-data entity datamodel

在我现有的iPhone-Project中实现Core Data时遇到了一些麻烦。首先,我想给你一个更详细的观点:

  • 我的一些类彼此嵌套:类“Game”有一个NSArray,对象类为“Player”,类“Player”有一个NSArray,依次为“Item”类对象。

  • 我想做的是保存我“最高级”课程“游戏”的实例(例如离开我的应用程序时)。

我尝试了一些关于核心数据的教程,但仍有一些问题:

  1. 我是否必须为每个班级创建一个实体,或仅为“游戏”创建一个实体?
  2. 如果我必须为每一个做这个:我想我必须在我的类之间创建所有关系,但是:如何创建关系,例如在“游戏”和“玩家”之间(请提醒:我在一个NSArray中拥有许多玩家)..
  3. 如何更改现有项目?我所做的就是将丢失的方法复制到我的AppDelegate中。但是我将如何处理我的课程,特别是使用Getter / Setter方法?只需在实现中将“@synthesize”更改为“@dynamic”吗?
  4. 我希望在黑暗中有一些亮光;)

    现在非常感谢

    Mac1988

2 个答案:

答案 0 :(得分:2)

我建议在xcode中设置数据库模型,然后在完成后...选择实体并从菜单File>中选择。新文件。然后从“Cocoa touch class”中选择“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是我的存在类,快速列表是我的coredata类。

答案 1 :(得分:1)

  1. 是的,您想为您提到的所有课程创建一个实体。

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

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

  4. 例如,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
    

    另外,修改播放器和项目属性时要小心。核心数据编程指南的Using Managed Objects部分有很多很好的细节,但基本上要将一个播放器添加到游戏实例中,你会这样做

    [game addPlayerObject:newPlayer];
    

    要实际创建新玩家,您可以执行以下操作:

    NSManagedObject *newPlayer = [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:context];