草庐IT

ios - NSCoding 和保存/加载默认值问题

coder 2023-09-29 原文

我正在为 iPhone 应用程序编写一些代码,但在正确加载默认数据时遇到了问题。我的代码基于 Ray Wenderlich 的“Learning Cocos2d”一书中的一些示例。

似乎即使我彻底删除应用程序并尝试从新数据开始,应用程序也不一致地不尝试加载数据,或者错误地认为有数据,并加载空值。

我正在使用 containsValueForKey 来检查值是否存在,然后加载它或加载一些默认值,但即使在全新安装中,containsValueForKey 也会查找数据并且不会加载默认值。在 xcode 的管理器中,我检查了我设备的文件结构和我指定要保存的文档文件夹,看起来它不包含任何文件,所以我不确定它在抓取什么。

我的猜测是问题与 initWithCoder 函数有关。它有时似乎神秘地经历了这个功能,但并非总是如此。另一个奇怪的事情是当玩家获得高分时我调用了[[GameManager sharedGameManager] save](这里没有显示,但是代码和这个objectiveList完全一样,只是一个int)并且它出现了才能正确保存。

现在是代码:

GC数据库.h

#import <Foundation/Foundation.h>
id loadData(NSString * filename);
void saveData(id theData, NSString *filename);

GC数据库.m

#import "GCDatabase.h"
NSString * pathForFile(NSString *filename) {
// 1
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
// 2
NSString *documentsDirectory = [paths objectAtIndex:0];
// 3
return [documentsDirectory stringByAppendingPathComponent:filename];
}

id loadData(NSString * filename) {

NSString *filePath = pathForFile(filename);
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {

    NSData *data = [[[NSData alloc] initWithContentsOfFile:filePath] autorelease];
    NSKeyedUnarchiver *unarchiver = [[[NSKeyedUnarchiver alloc] initForReadingWithData:data] autorelease];
    id retval = [unarchiver decodeObjectForKey:@"Data"];
    [unarchiver finishDecoding];
    return retval;
}
return nil;
}

void saveData(id theData, NSString *filename) {

NSMutableData *data = [[[NSMutableData alloc] init] autorelease];
NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
[archiver encodeObject:theData forKey:@"Data"];
[archiver finishEncoding];
[data writeToFile:pathForFile(filename) atomically:YES];
}

游戏管理器.h

@interface GameManager : NSObject <NSCoding>{
NSMutableArray *objectiveDescriptions;
}
@property (nonatomic, retain) NSMutableArray * objectiveDescriptions;
+(GameManager*)sharedGameManager;
-(void)save;
-(void)load;
-(void)encodeWithCoder:(NSCoder *)encoder;
-(id)initWithCoder:(NSCoder *)decoder;

@end

GameManager.m(我加了load函数,试图强制加载,但是好像不行)

+(GameManager*)sharedGameManager {
@synchronized([GameManager class])
{
    if(!sharedGameManager) {
        sharedGameManager = [loadData(@"GameManager") retain];
        if (!sharedGameManager) {
            [[self alloc] init];
        }
    }
    return sharedGameManager;
}
return nil; 
}

+(id)alloc {
@synchronized([GameManager class]){
    NSAssert(sharedGameManager == nil, @"Attempted to allocate a second instance of the Game Manager singleton");
    sharedGameManager = [super alloc];
    return sharedGameManager;
}
return nil;
}

- (void)dealloc {
[objectiveList release];
[super dealloc];
}

- (void)save {
saveData(self, @"GameManager");
}

-(void)load {
loadData(@"GameManager");
}

- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:objectiveList forKey:@"objectiveList"];
}

- (id)initWithCoder:(NSCoder *)decoder  {
self = [super init];
if (self != nil) {
if ([decoder containsValueForKey:@"objectiveList"]) {
        objectiveList = [decoder decodeObjectForKey:@"objectiveList"];
    } else {
        [objectiveList addObjectsFromArray:[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"5", nil]];
    }
}

return self;
}
@end

最佳答案

我没有阅读你的完整代码..但我发现代码中有问题....

您还没有为 objectiveList 数组分配内存。除非并且直到您为数组分配内存,否则不会添加对象...

我想去

 objectiveList = [[NSMutableArray alloc] initWithArray:[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"5", nil]];

代替

    [objectiveList addObjectsFromArray:[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"5", nil]];

检查语法..希望这可能会有所帮助,因为在过去我忘记为数组分配内存时它也困扰着我..并继续添加对象导致空...:) 如果它不能解决您的问题,我稍后会完全查找代码.. :)

关于ios - NSCoding 和保存/加载默认值问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10453498/

有关ios - NSCoding 和保存/加载默认值问题的更多相关文章

  1. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  2. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  3. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  4. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  5. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  6. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  7. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  8. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

  9. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  10. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

随机推荐