将核心数据应用到现有的 iPhone 项目中

发布于 2024-08-13 05:27:24 字数 600 浏览 9 评论 0原文

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

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

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

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

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

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

现在非常感谢

Mac1988

I´ve some trouble with implementing Core Data to my existing iPhone-Project. First I wanna give you a more detailed view on it:

  • Some of my classes are nested into each other: The class "Game" has an NSArray with objects of class "Player", the class "Player" has an NSArray with objects of class "Item" in turn.

  • What I wanna do is saving an instance of my "uppest" class "Game" (e.g. when leaving my app).

I tried out some tutorials about Core Data, but there are still some questions:

  1. Do I have to create an entity for each of my classes or just for "Game"?
  2. If I have to do it for each one: I think I will have to create ALL relationships between my classes, but: How to create the relationships e.g. between "Game" an "Player" (please remind: I hold MANY players in ONE NSArray)..
  3. What about changing my existing project? What I allready did is copying the missing methods into my AppDelegate. But what will I have to do with my classes, especially with Getter/Setter-methods? Just change "@synthesize" to "@dynamic" in the implementation?

I hope for some light in my dark ;)

Thanks a lot right now

Mac1988

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

娇纵 2024-08-20 05:27:24

我建议在 xcode 中设置数据库模型,然后当您完成此操作后...选择实体并从菜单“文件”>“选择”中选择。新文件。然后从“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 是我现有的类,quicklist 是我的 coredata 类。

What I recommend is to setup your database model in xcode, then when you have done that... choose the entities and choose from the menu File > New File. Then choose the "Managed Object Class" from the "Cocoa touch class". After "Next" choose where to save the files, and at the next step XCode will ask you which entities should be generated to files.

After you have done that, you can implement the functions you need into your e.g. you delegate. My recommendation is to leave your existing stuff as it is and use the core data classes as their own. Just pull the data you need from you existing classes/arrays and put them in to the database as you need them. When retrieving, the other way around... get them from the DB and add them to your functions / classes.

Example from one of my projects:

The .h file

@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

The .m file

#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

EDIT:
The quicklistSet was my existsing class, the quicklist is my coredata class.

燃情 2024-08-20 05:27:24
  1. 是的,您希望为您提到的所有类创建一个实体。

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

  3. 您需要让数据类(Game、Player、Item)继承自 NSManagedObject。您可能想要删除与您在核心数据中添加的属性相对应的所有实例变量。对于多对多关系(玩家、物品),您肯定会想要删除您正在使用的 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

另外,修改玩家和物品属性时要小心。的使用托管对象部分核心数据编程指南有很多很好的细节,但基本上要将玩家添加到游戏实例,您会做

[game addPlayerObject:newPlayer];

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

NSManagedObject *newPlayer = [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:context];
  1. Yes, you want to create an entity for all of the classes you mentioned.

  2. You've already got the answer to this in your question: make a one-to-many relationship. For example, for the players relationship of Game, click the "To-many relationship" checkbox in the data model editor.

  3. You'll want to have your data classes (Game, Player, Item) inherit from NSManagedObject. You'll probably want to remove all of the instance variables that correspond to the attributes you added in Core Data. For the to-many relationships (players, items), you'll definitely want to get rid of the NSArray member variable you were using. Instead, do like you were saying and create @dynamic accessors for the players and items properties. Note that you want to use an NSSet instead of an NSArray for players and items.

For example, the header for your Game class might look like this:

@interface Game : NSManagedObject {

}

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

@end

And then your implementation file might look like:

#import "Game.h"

@implementation Game

@dynamic players, someOtherProperty, yetAnotherProperty;

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

// other methods go here

@end

Also, be careful when modifying the players and items properties. The Using Managed Objects section of the Core Data Programming guide has a lot of good details, but basically to add a Player to a Game instance, you would do

[game addPlayerObject:newPlayer];

To actually create the new player, you would do something like:

NSManagedObject *newPlayer = [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:context];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文