- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
免责声明:主要菜鸟
我正在编写一个算术闪存卡应用程序作为一个学习项目。我有一个带有底部选项卡栏的 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 类型使用 YES
和 NO
而不是 TRUE
和 FALSE
) 您将使用类似这样的东西,通常在应用程序主类的 +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)或通知。在这种情况下,出于以下原因,我将使用通知:
因此,在您的 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/
我需要修复 getLineNumberFor 方法,以便如果 lastName 的第一个字符位于 A 和 M 之间,则返回 1;如果它位于 N 和 Z 之间,则返回 2。 在我看来听起来很简单,但我不
您好,感谢您的帮助!我有这个: 0 我必须在每次点击后增加“pinli
Javascript 中是否有一种方法可以在不使用 if 语句的情况下通过 switch case 结构将一个整数与另一个整数进行比较? 例如。 switch(integer) { case
我有一列是“日期”类型的。如何在自定义选项中使用“之间”选项? 最佳答案 请注意,您有2个盒子。 between(在SQL中)包含所有内容,因此将框1设置为:DATE >= startdate,将框2
我有一个表,其中包含年、月和一些数字列 Year Month Total 2011 10 100 2011 11 150 2011 12 100 20
这个问题已经有答案了: Extract a substring between double quotes with regular expression in Java (2 个回答) how to
我有一个带有类别的边栏。正如你在这里看到的:http://kees.een-site-bouwen.nl/ url 中类别的 ID。带有 uri 段(3)当您单击其中一个类别时,例如网页设计。显示了一
这个问题在这里已经有了答案: My regex is matching too much. How do I make it stop? [duplicate] (5 个答案) 关闭 4 年前。 我
我很不会写正则表达式。 我正在尝试获取括号“()”之间的值。像下面这样的东西...... $a = "POLYGON((1 1,2 2,3 3,1 1))"; preg_match_all("/\((
我必须添加一个叠加层 (ImageView),以便它稍微移动到包含布局的左边界的左侧。 执行此操作的最佳方法是什么? 尝试了一些简单的方法,比如将 ImageView 放在布局中并使用负边距 andr
Rx 中是否有一些扩展方法来完成下面的场景? 我有一个开始泵送的值(绿色圆圈)和其他停止泵送的值(簧片圆圈),蓝色圆圈应该是预期值,我不希望这个命令被取消并重新创建(即“TakeUntil”和“Ski
我有一个看起来像这样的数据框(Dataframe X): id number found 1 5225 NA 2 2222 NA 3 3121 NA 我有另一个看起来
所以,我正在尝试制作正则表达式,它将解析存储在对象中的所有全局函数声明,例如,像这样 const a = () => {} 我做了这样的事情: /(?:const|let|var)\s*([A-z0-
我正在尝试从 Intellivision 重新创建 Astro-Smash,我想让桶保持在两个 Angular 之间。我只是想不出在哪里以及如何让这个东西停留在两者之间。 我已经以各种方式交换了函数,
到处检查但找不到答案。 我有这个页面,我使用 INNER JOIN 将两个表连接在一起,获取它们的值并显示它们。我有这个表格,用来获取变量(例如开始日期、结束日期和卡号),这些变量将作为从表中调用值的
我陷入了两个不同的问题/错误之间,无法想出一个合适的解决方案。任何帮助将不胜感激 上下文、FFI 和调用大量 C 函数,并将 C 类型包装在 rust 结构中。 第一个问题是ICE: this pat
我在 MySQL 中有一个用户列表,在订阅时,时间戳是使用 CURRENT_TIMESTAMP 在数据库中设置的。 现在我想从此表中选择订阅日期介于第 X 天和第 Y 天之间的表我尝试了几个查询,但不
我的输入是开始日期和结束日期。我想检查它是在 12 月 1 日到 3 月 31 日之间。(年份可以更改,并且只有在此期间内或之外的日期)。 到目前为止,我还没有找到任何关于 Joda-time 的解决
我正在努力了解线程与 CPU 使用率的关系。有很多关于线程与多处理的讨论(一个很好的概述是 this answer )所以我决定通过在运行 Windows 10、Python 3.4 的 8 CPU
我正在尝试编写 PHP 代码来循环遍历数组以创建 HTML 表格。我一直在尝试做类似的事情: fetchAll(PDO::FETCH_ASSOC); ?>
我是一名优秀的程序员,十分优秀!