【问题标题】:Setting up a plist to store application data (not settings) for an iPhone game设置 plist 以存储 iPhone 游戏的应用程序数据(不是设置)
【发布时间】:2011-02-06 04:59:29
【问题描述】:

我正在编写一个 iPhone 游戏,它可以很好地处理我的硬编码关卡数据,但我想将关卡数据存储在 plist 中,并在启动时加载它。我从未使用过 plist,并且无法理解如何根据我的数据模型设置 plist。

这是我现在对其进行硬编码的方式:

(在我的 appDelegate 中)

- (void)loadLevels {
    //setup NSNumber objects to load into sequences
    NSNumber * rID = [[[NSNumber alloc] initWithInt:0] autorelease];
    NSNumber * bID = [[[NSNumber alloc] initWithInt:1] autorelease];
    NSNumber * gID = [[[NSNumber alloc] initWithInt:2] autorelease];
    NSNumber * yID = [[[NSNumber alloc] initWithInt:3] autorelease];
    NSNumber * rbID = [[[NSNumber alloc] initWithInt:4] autorelease];
    NSNumber * rgID = [[[NSNumber alloc] initWithInt:5] autorelease];
    NSNumber * ryID = [[[NSNumber alloc] initWithInt:6] autorelease];
    NSNumber * bgID = [[[NSNumber alloc] initWithInt:7] autorelease];
    NSNumber * byID = [[[NSNumber alloc] initWithInt:8] autorelease];
    NSNumber * gyID = [[[NSNumber alloc] initWithInt:9] autorelease];

    //Level One's Sequence
    NSMutableArray * aSequence = [[[NSMutableArray alloc] initWithCapacity:1] autorelease];

    [aSequence addObject: rID];
    [aSequence addObject: bID];
    [aSequence addObject: gID];
    [aSequence addObject: yID];
    [aSequence addObject: rbID];
    [aSequence addObject: rgID];
    [aSequence addObject: ryID];
    [aSequence addObject: bgID];
    [aSequence addObject: byID];
    [aSequence addObject: gyID];

    // Load level One
    _levels = [[[NSMutableArray alloc] init] autorelease];

    Level *level1 = [[[Level alloc] initWithLevelNum:1 levelSpeed:1.0 levelSequence:aSequence] autorelease];

    [_levels addObject:level1];
 //do the same thing for subsequent levels//
}

(这就是我实现关卡类的方式)

#import "Level.h"

@implementation Level

@synthesize levelNum = _levelNum;
@synthesize levelSpeed = _levelSpeed;
@synthesize levelSequence = _levelSequence;

- (id)initWithLevelNum:(int)levelNum levelSpeed:(float)levelSpeed levelSequence:(NSMutableArray *)levelSequence {
    if ((self = [super init])) {
        self.levelNum = levelNum;
        self.levelSpeed = levelSpeed;
        self.levelSequence = [[[NSMutableArray alloc] initWithArray:levelSequence] autorelease];
    }
    return self;
}

- (void)dealloc {
    [_levelSequence release];
    _levelSequence = nil;
    [super dealloc];
}

@end

我只是不知道如何设置一个 plist 来存储我的数据以匹配我的模型。谁能给我一些建议吗?

补充: (这就是我认为我需要设置 plist 的方式 - 数据模型只是初始化我的级别的三个变量(上图)。如果您查看我当前的 plist,可能会更清楚它是如何设置的,但每个级别都包含of:关卡编号、关卡速度和表示该关卡所需顺序的数字数组。)

现在,如果我的设置正确,我该如何将值加载到我的程序中?

【问题讨论】:

  • 嗯,你的型号是什么?你没有在这里向我们展示。
  • @Jonathan Grynspan 我更新了我的问题,提供了有关我的数据的更多详细信息。希望这有助于理解我想要做什么。

标签: ios objective-c iphone xcode plist


【解决方案1】:
  • 将您的 plist 文件添加为项目中的资源文件。比如说,它的名字是config.plist

  • 获取资源文件的路径。 (不过,请注意 [NSBundle mainBundle],因为它不会在单元测试中返回单元测试包。)

NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"config" ofType:@"plist"];
  • 您的根对象是一个级别数组。将其加载到 NSArray 中。
// 这是自动释放的。如果需要,您可以保留它 NSArray *levelArray = [NSArray arrayWithContentsOfFile:plistPath];
  • 现在您有了关卡数组。每个级别都是一个字典。加载第 i 层(从 ​​0 开始计数)。
NSDictionary *level = [levelArray objectAtIndex:i];
  • 现在您可以使用 objectForKey 方法从关卡字典中获取对象。比如获取序列数组:
NSArray *seq = [level objectForKey:@"levelSequence"];
  • 您可以循环访问 levelArray 以分配、初始化和添加所有级别的级别数组。

希望对您有所帮助。请注意,我没有编译代码,所以可能有一些拼写错误。

【讨论】:

  • 感谢您简洁明了的回答。正如我在@Alexsander 的回答中指出的那样,我根本不需要更新这个 plist 中的数据,它是静态的,所以这种方法似乎最适合我的需要!现在有一个关于 KVC 的问题:因为我的 plist 是字典数组,这是否意味着它不符合 KVC?或者字典部分将字符串作为第一个键这一事实是否使其符合 KVC? (这不是我的应用程序的真正要求,但我认为包含在此讨论中会很有见地。)
  • @Mark,我认为对于静态配置数据,使用 plist 比 NSUserDefaults 更好。和你一样,我也更喜欢 NSUserDefaults 用于可以更改的数据,例如用户偏好或游戏中的最佳得分。但对于静态配置,我更喜欢 plist。就像我们在其他平台上使用 XML 配置文件的方式一样。 plist 也是 XML,具有特定元素。关于KVC,很抱歉我在这方面没有太多经验。所以我不应该评论KVC。让我们看看其他成员的建议。
【解决方案2】:

您应该做的是创建一个包含您想要的所有适用数据的NSDictionary,然后读取它并将其写入NSUserDefaults

【讨论】:

  • @Alexsander Akers 我看过NSUserDefaults,但从我读到的内容来看,我认为它更适合用于保存应用程序设置而不是应用程序数据。我错了吗?
  • @Mark7777G:这是它的预期目的,但您可以将任何可以存储在 plist 中的内容存储在其中。对于您想要存储的静态数据,我会说将其存储在应用程序包内的 plist 中(如前所述)是一种更传统的方法。
  • 在我上一条评论的基础上,NSUserDefaults 会定期同步到磁盘 - 使用大量数据可能会产生不必要的开销。
  • @Alexsander Akers 好的,这是有道理的,我正在考虑使用 NSUserDefaults 来存储应用程序设置和首选项 - 所以这可能不会像你提到的那样开销太大。我认为 taskinoor 的解决方案最适合我对应用程序数据部分的需求,尤其是因为我根本不需要更新此信息 - 它是静态的。
  • 所以我想读者可以从中得到的总结是针对少量数据(尤其是您不需要经常同步的数据),应用程序包中的 plist 是最好的方法;但是,NSUserDefaults 方法最适合需要经常同步的设置/首选项和数据。 plist/应用程序包解决方案的另一个最佳用途是否可以用于仅在应用程序终止时需要更新的已保存游戏数据/辞职活跃?此外,我是否正确地说如果您有大量数据SQLlite 是最好的存储解决方案?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多