【问题标题】:Xcode/iOS NSUserDefaults acting StrangeXcode/iOS NSUserDefaults 行为奇怪
【发布时间】:2014-09-10 03:34:33
【问题描述】:

我正在尝试使用 NSUserDefaults 进行我的第一个保存项目,但发生了一些奇怪的事情。

在我的应用程序委托中,在做太多事情之前,我会切换几个变量。

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

if (![defaults objectForKey:@"firstRun"]){
    //flag doesnt exist then this IS the first run
    self.firstRun = TRUE;

    NSLog(@"FIRST RUN");

    //store the flag so it exists the next time the app starts
    [defaults setObject:[NSDate date] forKey:@"firstRun"];
    NSLog(@"%s world2 before",[defaults objectForKey:@"world2"] ? "true" : "false" );
    [defaults setBool:false forKey:@"world2"];
    NSLog(@"%s world2 after",[defaults objectForKey:@"world2"] ? "true" : "false" );
}else{
    //flag does exist so this ISNT the first run
    self.firstRun = FALSE;
    NSLOG(@"NOT FIRST RUN");
    NSLog(@"%s world2",[defaults objectForKey:@"world2"] ? "true" : "false" );

}
[[NSUserDefaults standardUserDefaults] synchronize];

这样做,当我运行应用程序时,这就是我在控制台中得到的(第一次运行时)

2014-09-09 22:15:57.794 GameName[30151:907] FIRST RUN
2014-09-09 22:15:57.795 GameName[30151:907] false world2 before
2014-09-09 22:15:57.795 GameName[30151:907] true world2 after

我不明白为什么在将其设置为假之前,它是假的(当然,好的) - 但在将其设置为假之后,它是真的!嗯?

我也尝试过设置为 true、YES、NO,以及将 NSNumber 与 Bool 一起使用。

我的完整应用委托:

.h

#import <UIKit/UIKit.h>
#import "cocos2d.h"
#import "GameLevelLayer.h"
@interface AppController : CCAppDelegate
{
    GameLevelLayer *currentLevel;
}
@property(nonatomic) BOOL firstRun;


@end

.m

#import "cocos2d.h"

#import "AppDelegate.h"
#import "CCBuilderReader.h"


@implementation AppController
@synthesize firstRun = _firstRun;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:        (NSDictionary *)launchOptions
{
    // Configure Cocos2d with the options set in SpriteBuilder
    NSString* configPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Published-iOS"]; // TODO: add support for Published-Android support
    configPath = [configPath stringByAppendingPathComponent:@"configCocos2d.plist"];

    NSMutableDictionary* cocos2dSetup = [NSMutableDictionary dictionaryWithContentsOfFile:configPath];

    // Note: this needs to happen before configureCCFileUtils is called, because we need apportable to correctly setup the screen scale factor.
#ifdef APPORTABLE
    if([cocos2dSetup[CCSetupScreenMode] isEqual:CCScreenModeFixed])
        [UIScreen mainScreen].currentMode = [UIScreenMode emulatedMode:UIScreenAspectFitEmulationMode];
    else
    [UIScreen mainScreen].currentMode = [UIScreenMode emulatedMode:UIScreenScaledAspectFitEmulationMode];
#endif

    // Configure CCFileUtils to work with SpriteBuilder
    [CCBReader configureCCFileUtils];

    // Do any extra configuration of Cocos2d here (the example line changes the pixel format for faster rendering, but with less colors)
    //[cocos2dSetup setObject:kEAGLColorFormatRGB565 forKey:CCConfigPixelFormat];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    if (![defaults objectForKey:@"firstRun"]){
        //flag doesnt exist then this IS the first run
        self.firstRun = TRUE;

        NSLog(@"FIRST RUN");

        //store the flag so it exists the next time the app starts
        [defaults setObject:[NSDate date] forKey:@"firstRun"];
        NSLog(@"%s world2 before",[defaults objectForKey:@"world2"] ? "true" : "false" );
        [defaults setBool:false forKey:@"world2"];
        NSLog(@"%s world2 after",[defaults objectForKey:@"world2"] ? "true" : "false" );
    }else{
        //flag does exist so this ISNT the first run
        self.firstRun = FALSE;
        NSLog(@"NOT FIRST RUN");
        NSLog(@"%s world2",[defaults objectForKey:@"world2"] ? "true" : "false" );

    }
    [[NSUserDefaults standardUserDefaults] synchronize];

    [self setupCocos2dWithOptions:cocos2dSetup];

    return YES;
}

【问题讨论】:

  • 如果您记录了返回的值会更有建设性。看实际数据!
  • 记录返回的值?不知道你的意思>.
  • 日志:[defaults objectForKey:@"world2"] 喜欢:NSLog(@"%@ world2 after", [defaults objectForKey:@"world2"]);
  • 杜帕杜! facepalm 非常感谢你

标签: ios objective-c xcode


【解决方案1】:

看来日志条件不正确。您正在使用“setBool”方法设置值。在检索您使用“objectForKey”方法时。

[defaults objectForKey:@"world2"] ? "true" : "false";

上述行返回“true”,因为它检查用户默认值是否具有键“world2”的值。因此,将该行更改为

 [defaults boolForKey:@"world2"] ? "true" : "false"

【讨论】:

  • 非常感谢,试图通过这些东西挑衅是行不通的。这将教会我更加注意!我很感激。
【解决方案2】:

你需要使用:

- (BOOL)boolForKey:(NSString *)defaultName

不是:

- (id)objectForKey:(NSString *)defaultName

后者返回一个对象,表示 false,因此NSLog() 中的测试报告 true 表示返回了某些内容。

所以代码是:

[defaults boolForKey:@"world2"]

【讨论】:

  • 非常感谢,试图通过这些东西挑衅是行不通的。这将教会我更加注意!我很感激。希望我能接受这两个答案!
猜你喜欢
  • 1970-01-01
  • 2013-02-09
  • 2014-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-23
  • 2014-07-02
相关资源
最近更新 更多