【问题标题】:implementing core data to an existing iPhone-project将核心数据实施到现有的 iPhone 项目中
【发布时间】:2010-12-21 22:16:16
【问题描述】:

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

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

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

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

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

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

现在非常感谢

Mac1988

【问题讨论】:

    标签: iphone core-data entity datamodel


    【解决方案1】:

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

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

    来自我的一个项目的示例:

    .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 类。

    【讨论】:

    • 嗨,保罗,谢谢你的回答和你的榜样。你的意思是创建一个由Core Data处理的新类“GameData”,然后“从那里”拉出并保存我的对象,对吧?我仍然完全不明白的是如何创建实体:例如一个属性“播放器”和与我现有的“播放器”类的多对多关系?还是我也必须创建一个新的“玩家”类?还是这一切都是可怕的错误? ;)
    • 我明白你的意思,但我不能直接回答你。我对核心数据还太缺乏经验。我所知道的是,每个实体的核心数据都会创建一个包含动态值的类。您也可以设置彼此之间的关系,但是您只需向实体添加另一个类。我认为你也必须创建一个新的玩家类,但也许有更多经验的人可以更好地回答你的问题。祝你好运!
    【解决方案2】:
    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];
    

    【讨论】:

      猜你喜欢
      • 2011-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-12
      • 2014-10-16
      • 2012-09-23
      • 2021-12-06
      相关资源
      最近更新 更多