如何实现NSUserDefault通过多视图访问



我试图在多个视图中共享字符串和整数,在iOS开发入门课程的最终项目中,大约50,我想知道我该怎么做……我知道MVC范式是最好的,但我们没有讲到非常高级的东西,尤其是core data。我想使用NSUserDefaults,我知道这是错误的,但这个应用不需要非常快,我认为这是最简单的方法。我的问题是,我将在哪里以及如何声明我将使用的NSUserDefault对象?我们在课堂上唯一一次使用它是在一个视图中。如果我在加载的第一个视图中声明它,我知道我可以在其他视图中访问它但我需要将第一个视图的头文件导入到其他视图中吗?


更新

所以我想让NSUserDefaults成为所有ViewControllers的一个属性,让事情变得更简单。然后,为了尝试获得值,我将每个ViewControllers的头实现到需要访问存储在NSUserDefaults(也具有NSUserDefault属性)中的数据的视图中。这个应用运行得很糟糕,直到我到达那个屏幕,没有任何更新。我确信我的错误在于我如何实现NSUserDefaults的某个地方,但我不确定如何正确地做到这一点。当我们在课堂上复习它们时(实际上这是一个"Sam’s Teach Yourself iPhone Application Development in 24 hours"的定向学习(这让我很生气)),我们唯一一次使用它们是在一个单视图应用程序中,它改变了白色背景的alpha值,这样它就可以用作闪光灯。它是这样呈现的:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setInteger: var forKey: kVar];
[userDefaults synchronize];

这是我在我的应用程序中尝试的:

在我的ViewController.h文件为每个视图:

...
@interface AppetizerViewController : UIViewController{
NSUserDefaults *userDefaults;
...
}
@property(assign)NSUserDefaults *userDefaults;

然后当我点击一个按钮时,我想把这个值保存为userDefaults:

-(IBAction)plusEgg:(id)sender{
eggs++;
eggString = [NSString stringWithFormat:@"%d",eggs];
eggQty.text = eggString;
eggOrderedQty.text = eggString;
[userDefaults setInteger:eggs forKey:kEggQty];
[userDefaults synchronize];
[self updateAppSubtotal];
}
-(IBAction)minusEgg:(id)sender{
eggs--;
if(eggs < 0){
eggs = 0;
}
eggString = [NSString stringWithFormat:@"%d",eggs];
eggQty.text = eggString;
eggOrderedQty.text = eggString;
[userDefaults setInteger:eggs forKey:kEggQty];
[userDefaults synchronize];
[self updateAppSubtotal];
} 

然后,由于我在所有视图的头文件中都有NSUserDefault Keys的所有常量,因此我将所有头文件实现为BillViewController,并尝试像这样访问它们:

-(void)populateLabels{
pieFinalQty.text = [NSString stringWithFormat:@"%d",
[userDefaults integerForKey:kPieQty]];
hazFinalQty.text = [NSString stringWithFormat:@"%d",
[userDefaults integerForKey:kHazQty]];
briFinalQty.text = [NSString stringWithFormat:@"%d",
[userDefaults integerForKey:kBriQty]];
choFinalQty.text = [NSString stringWithFormat:@"%d",
[userDefaults integerForKey:kChoQty]];
iceFinalQty.text = [NSString stringWithFormat:@"%d",
[userDefaults integerForKey:kIceQty]];
}

-(void)getSubtotal{
NSString *preSubString;
NSString *subString;
subFloat = [userDefaults floatForKey:kAppSub]+[userDefaults floatForKey:kBevSub]+
[userDefaults floatForKey:kDesSub]+
[userDefaults floatForKey:kEntSub]+[userDefaults floatForKey:kSidSub];
if(subFloat < 10){
preSubString = [[NSString alloc]initWithFormat:@"%1.2f",subFloat];
}else if(subFloat < 100 && subFloat >= 10){
preSubString = [[NSString alloc]initWithFormat:@"%2.2f",subFloat];
}else if(subFloat < 1000 && subFloat >= 100){
preSubString = [[NSString alloc]initWithFormat:@"%3.2f",subFloat];
}else{
preSubString = [[NSString alloc]initWithFormat:@"%4.2f",subFloat];
}
subString = [[NSString alloc]initWithFormat:@"$%@",preSubString];
billSubtotal.text = subString;
[preSubString release];
[subString release];
} 

我很抱歉,你们试图向我解释的东西显然完全超出了我的理解,我的命名习惯有点他妈的,但我已经连续工作了大约15个小时,很少休息,现在大约凌晨4点在MN这里。我该怎么做呢?我也很抱歉,它可能必须明确说明如何实现它。

关于NSUserDefaults的好处是您不需要在任何地方实例化它:它已经可以从应用程序中的任何地方访问。只需调用[NSUserDefaults standardUserDefaults],并对该对象进行读写。在对象上调用synchronize以确保更改存储在磁盘上,然后在您检索standardUserDefaults对象的下一个地方它将具有更新的信息。

Edit:根据上面的代码,您可以进行以下更改以利用标准用户默认对象:

  1. 删除@property (assign) NSUserDefaults userDefaults;和成员变量NSUserDefaults userDefaults;
  2. 在你想要读取或写入用户默认值的地方,创建一个临时变量:NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

你可以这样做的另一种方式,这似乎是你想做的,将@property设置为标准用户默认对象,这样它就不必通过调用standardUserDefaults来检索(因为看起来你使用它相当多,这可能是你应该去的方式)。

这样做:

  1. 留下你的@property,但将其设置为(retain)而不是(assign)(standardUserDefaults对象是autoreleased,所以你需要自己坚持下去)。(可选)您可以删除NSUserDefaults userDefaults;行,因为@property无论如何都会为您创建它
  2. 当你初始化你的视图控制器(或在viewDidLoad,就像我在这里做的),设置userDefaults变量为标准用户默认对象:

    - (void)viewDidLoad
    {
    [super viewDidLoad];
    self.userDefaults = [NSUserDefaults standardUserDefaults];
    }
    
  3. 释放初始化方法对应的方法中的用户默认变量(dealloc用于init方法,或viewDidUnload用于viewDidLoad):

    - (void)viewDidUnload
    {
    self.userDefaults = nil;
    }
    

没有什么要"声明"的。每当您说[NSUserDefaults standardUserDefaults]时,无论您从哪里说,您都在访问用户默认值。如果你需要设置默认值(即某些键的初始值),请在程序的早期完成,例如在应用程序委托的applicationDidFinishLaunching中,通过调用registerDefaults

如果你使用NSUserDefaults很多,那么它可能是方便的创建自己的类别,以确保你不会得到错别字在你的键。例如,假设我经常获取和设置值,那么让编译器做一些检查来确保我没有键入错误的键,当然我们都喜欢自动完成。

// NSUserDefaults+PSProperties.h
@interface NSUserDefaults (PSProperties)
@property (nonatomic, assign) NSInteger ps_myInteger;
@end
// NSUserDefaults+PSProperties.m
NSString * const PSKeyMyInteger = @"PSKeyMyInteger";
@implementation NSUserDefaults (PSProperties)
- (NSInteger)ps_myInteger;
{
return [self integerForKey:PSKeyMyInteger];
}
- (void)setPs_myInteger:(NSInteger)ps_myInteger;
{
[self setInteger:ps_myInteger forKey:PSKeyMyInteger];
}
@end
因此,在其他使用用户默认值的类中,我可以这样做:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
defaults.ps_myInteger = 5;
[defaults synchronize];
NSLog(@"%i", defaults.ps_myInteger);
> 2011-12-14 01:10:28.041 SampleUserDefaults[5356:f803] 5

现在所有的键都被隐藏了,我使用一个更好的API与NSUserDefaults交互,这与我的应用程序相关。

最新更新