gpt4 book ai didi

iphone - 无法在 View 之间读取 NSUserDefaults 数据

转载 作者:搜寻专家 更新时间:2023-10-30 19:53:00 25 4
gpt4 key购买 nike

免责声明:主要菜鸟

我正在编写一个算术闪存卡应用程序作为一个学习项目。我有一个带有底部选项卡栏的 UITabViewController,可以在几个不同的 View 之间切换。一切正常,直到我尝试在设置 View Controller 中设置 NSUserDefault bool 值并尝试在 Flashcards View Controller 中读取这些值。

设置 View 有一个开关来启用/禁用每个运算符(加法、减法等),如果启用了该类型的运算,抽认卡 View 应随机显示一张抽认卡。

我认为我的错误是我不理解数据封装、对象等的关键概念。如果有任何帮助,我将不胜感激。

这是设置 View Controller 。我什至不确定如何将代码放到这个论坛中,所以这可能是一个可笑的时刻......这里是:

//  settings_flashcards.h

#import <UIKit/UIKit.h>
@interface settings_flashcards : UIViewController {
UISwitch *additionSwitch;
UISwitch *subtractionSwitch;
UISwitch *multiplicationSwitch;
UISwitch *divisionSwitch;
}

@property (nonatomic,retain) IBOutlet UISwitch *additionSwitch;
@property (nonatomic,retain) IBOutlet UISwitch *subtractionSwitch;
@property (nonatomic,retain) IBOutlet UISwitch *multiplicationSwitch;
@property (nonatomic,retain) IBOutlet UISwitch *divisionSwitch;

@end

和...

/  settings_flashcards.m

#import "settings_flashcards.h"

@implementation settings_flashcards

@synthesize additionSwitch;
@synthesize subtractionSwitch;
@synthesize multiplicationSwitch;
@synthesize divisionSwitch;

- (void)viewDidLoad {

[additionSwitch addTarget:self action:@selector(additionSwitchFlipped) forControlEvents:UIControlEventValueChanged];
[subtractionSwitch addTarget:self action:@selector(subtractionSwitchFlipped) forControlEvents:UIControlEventValueChanged];
[multiplicationSwitch addTarget:self action:@selector(multiplicationSwitchFlipped) forControlEvents:UIControlEventValueChanged];
[divisionSwitch addTarget:self action:@selector(divisionSwitchFlipped) forControlEvents:UIControlEventValueChanged];
[super viewDidLoad];
}

-(void) additionSwitchFlipped {
if (additionSwitch.on) {
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:@"additionKey"];
}else {
[[NSUserDefaults standardUserDefaults] setBool:FALSE forKey:@"additionKey"];
}
}

-(void) subtractionSwitchFlipped {
if (subtractionSwitch.on) {
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:@"subtractionKey"];
}else {
[[NSUserDefaults standardUserDefaults] setBool:FALSE forKey:@"subtractionKey"];
}
}

-(void) multiplicationSwitchFlipped {
if (multiplicationSwitch.on) {
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:@"multiplicationKey"];
}else {
[[NSUserDefaults standardUserDefaults] setBool:FALSE forKey:@"multiplicationKey"];
}

}

-(void) divisionSwitchFlipped {
if (divisionSwitch.on) {
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:@"divisionKey"];
}else {
[[NSUserDefaults standardUserDefaults] setBool:FALSE forKey:@"divisionKey"];
}
}

这是抽认卡 View ...

//  flashcardsViewController.h

#import <UIKit/UIKit.h>

@interface flashcardsViewController : UIViewController <UIActionSheetDelegate>{

UILabel *firstNumberLabel;
UILabel *secondNumberLabel;
UILabel *answerNumberLabel;
UILabel *operatorLabel;

BOOL additionIsEnabled;
BOOL subtractionIsEnabled;
BOOL multiplicationIsEnabled;
BOOL divisionIsEnabled;
}

@property (nonatomic,retain) IBOutlet UILabel *firstNumberLabel;
@property (nonatomic,retain) IBOutlet UILabel *secondNumberLabel;
@property (nonatomic,retain) IBOutlet UILabel *answerNumberLabel;
@property (nonatomic,retain) IBOutlet UILabel *operatorLabel;

-(void) buttonClicked:(id)sender;

@end

和...

//  flashcardsViewController.m

#import "flashcardsViewController.h"

@implementation flashcardsViewController

@synthesize firstNumberLabel;
@synthesize secondNumberLabel;
@synthesize answerNumberLabel;
@synthesize operatorLabel;

- (void)viewDidLoad {

srand(time(0)); //seed random

//the following should assign the keys if they don't exist
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"additionKey"]){
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:@"additionKey"];
}


if (![[NSUserDefaults standardUserDefaults] boolForKey:@"subtractionKey"]) {
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:@"subtractionKey"];
}

if (![[NSUserDefaults standardUserDefaults] boolForKey:@"multiplicationKey"]) {
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:@"multiplicationKey"];

}

if (![[NSUserDefaults standardUserDefaults] boolForKey:@"divisionKey"]) {
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:@"divisionKey"];
}

//the following should assign each BOOL variable based on the key
additionIsEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"additionKey"];
subtractionIsEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"subtractionKey"];
multiplicationIsEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"multiplicationKey"];
divisionIsEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"divisionKey"];
[super viewDidLoad];
}

-(void) buttonClicked:(id)sender{

int a = rand() % 4;// random number generator (number to enter loop)

if ( additionIsEnabled || subtractionIsEnabled || multiplicationIsEnabled || divisionIsEnabled) {
while (a < 5) {
switch (a) {
case 0:
if (additionIsEnabled == TRUE){
int x = rand() % 11 + 1;
int y = rand() %11 + 1;
firstNumberLabel.text = [[NSString alloc]initWithFormat: @"%i",x];
secondNumberLabel.text = [[NSString alloc]initWithFormat: @"%i",y];
answerNumberLabel.text = [[NSString alloc]initWithFormat: @"%i",(x+y)];
operatorLabel.text = [[NSString alloc]initWithFormat: @"+"];
a = 5;
}
else a++;
break;
case 1:
if (subtractionIsEnabled == TRUE){
int x = rand() % 19 + 1;
int y = rand() %11 + 1;
firstNumberLabel.text = [[NSString alloc]initWithFormat: @"%i",x];
secondNumberLabel.text = [[NSString alloc]initWithFormat: @"%i",y];
answerNumberLabel.text = [[NSString alloc]initWithFormat: @"%i",(x-y) ];
operatorLabel.text = [[NSString alloc]initWithFormat: @"-"];
a = 5;
}
else a++;
break;
case 2:
if (multiplicationIsEnabled == TRUE){
int x = rand() % 11 + 1;
int y = rand() %11 + 1;
firstNumberLabel.text = [[NSString alloc]initWithFormat: @"%i",x];
secondNumberLabel.text = [[NSString alloc]initWithFormat: @"%i",y];
answerNumberLabel.text = [[NSString alloc]initWithFormat: @"%i",(x*y)];
operatorLabel.text = [[NSString alloc]initWithFormat: @"×"];
a = 5;
}
else a++;
break;
case 3:
if (divisionIsEnabled == TRUE){
int x = rand() % 11 + 1;
int y = rand() % 11 + 1;
firstNumberLabel.text = [[NSString alloc]initWithFormat: @"%i",(x*y)];
secondNumberLabel.text = [[NSString alloc]initWithFormat: @"%i",y];
answerNumberLabel.text = [[NSString alloc]initWithFormat: @"%i",x];
operatorLabel.text = [[NSString alloc]initWithFormat: @"÷"];
a = 5;
}
else a = 0;
break;
default:
break;
}
}
}
else
{
UIAlertView *noOperatorSelectedAlert = [[UIAlertView alloc]initWithTitle:@"You have not set any operations."
message:@"Return to the settings menu and decide which operations you wish to perform. (addition, subtraction, etc.)"
delegate:self
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[noOperatorSelectedAlert show];
[noOperatorSelectedAlert release];
}
}

最佳答案

这里有一些事情要做。首先,您需要一种更好的方式来说明在用户做出任何明确决定之前默认状态是什么。接下来您想知道什么时候应该根据用户偏好刷新您的应用内状态。

默认初始化

第一项的解决方案是将默认值放入您的用户首选项的注册域。这是您将在应用程序初始化期间执行的操作,而不是让您的 View 单独检查首选项并在初始化时更新它们。首选项系统会在很多地方查找数据,它查找的第一个位置是仅在内存中的注册域。这是您为每个用户首​​选项放置默认值(即没有指定值意味着“x”)的地方。

您将为此使用的 API 是 -[NSUserDefaults registerDefaults:],它采用 NSDictionary 值。要设置 YES 的默认值(在 Objective-C 中,BOOL 类型使用 YESNO 而不是 TRUEFALSE) 您将使用类似这样的东西,通常在应用程序主类的 +initialize 方法中执行:

+ (void) initialize
{
// in any +initialize, make sure it's being called on your class
// +initialize is different from all other methods in this respect
if ( [self isKindOfClass: [MyApplicationDelegate class]] == NO )
return; // being called on a superclass, don't do my stuff

// set up default values for certain preferences
NSMutableDictionary * defaults = [NSMutableDictionary new];
[defaults setObject: [NSNumber numberWithBool: YES] forKey: @"additionKey"];
[defaults setObject: [NSNumber numberWithBool: YES] forKey: @"subtractionKey"];
[defaults setObject: [NSNumber numberWithBool: YES] forKey: @"multiplicationKey"];
[defaults setObject: [NSNumber numberWithBool: YES] forKey: @"divisionKey"];

// set this as the registration domain
[[NSUserDefaults standardUserDefaults] registerDefaults: defaults];
[defaults release];
}

通常你会将一切放入一个这样的方法中,所以如果你的应用程序的其他部分需要任何首选项的默认非零值,你应该将它们添加到这个组中并将其放入应用程序委托(delegate)的 +initialize 方法中。

现在,当您的其他类使用 [[NSUserDefault standardUserDefaults] boolForKey: @"additionKey"] 并且没有任何内容保存到该键的首选项文件中时,它们将获得上面提供的值。

刷新缓存值

因此,您有一个 View ,用户可以在其中更改这些首选项。您的下一个工作是使上面的 View 使用新的首选项更新其成员变量。为此,我们可以使用委托(delegate)或通知。在这种情况下,出于以下原因,我将使用通知:

  1. 您使用的是 NSUserDefaults,理论上它可以在许多不同的地方发生变化。委派只会通知您一个对象所做的更改。
  2. NSUserDefaults 已经实现了一个方便的通知,您可以观看。

因此,在您的 flashcardsViewController 中,您将拥有类似于以下几种方法的内容:

- (void) updateFromPreferences
{
// fetch current values from user defaults into your member variables
additionIsEnabled = [[NSUserDefaults standardUserDefaults] boolForKey: @"additionKey"];
// etc...
}

- (void) viewWillLoad
{
// load variables from user defaults
[self updateFromPreferences];

// find out when the preferences have been changed
// this will cause -updateFromPreferences to be called
// whenever something changes preferences, inside the app or outside
[[NSNotificationCenter defaultNotificationCenter] addObserver: self
selector: @selector(updateFromPreferences)
name: NSUserDefaultsDidChangeNotification
object: nil];
}

- (void) viewDidUnload
{
// always remove notification observers.
[[NSNotificationCenter defaultNotificationCenter] removeObserver: self
name: NSUserDefaultsDidChangeNotification
object: nil];
}

- (void) dealloc
{
// add this to your existing dealloc routine
[[NSNotificationCenter defaultNotificationCenter] removeObserver: self
name: NSUserDefaultsDidChangeNotification
object: nil];
}

总结

综合起来,这两者应该可以为您提供完成这项工作所需的一切。

关于iphone - 无法在 View 之间读取 NSUserDefaults 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5121712/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com