How to implement NSUserDefault to access through multiple views

百般思念 提交于 2019-12-10 20:18:27

问题


I'm trying to share strings and integers throughout multiple views for a final project in an introductory iOS development course, around 50, and am wondering how I would go about doing this... I know the MVC paradigm is best but we didn't get to very advanced stuff, especially core data. I was thinking of using NSUserDefaults, I know it's wrong but this app doesn't have to be blazingly fast, and I think this would be the simplest way for me. My question is, where and how would I declare the NSUserDefault object I would be using? The only time in class that we used it was in one view. If I declare it in the first view that's loaded I know I can access it with the other views but do I need to import the header file of the first view into each of the others or will it be accessible regardless?


Update


So I thought I would try to make things easier by making NSUserDefaults a property in all of the ViewControllers. Then to attempt to get the values back I implemented the headers from each of the ViewControllers into the view that needs to access the data stored in NSUserDefaults (which also has an NSUserDefault property). The app runs terrifically until I get to that screen and nothing is updated. I'm sure my mistake lies somewhere in how I implemented the NSUserDefaults but I am unsure of how to do it correctly. When we went over them in class (actually it's a Directed Study with "Sam's Teach Yourself iPhone Application Development in 24 Hrs" (puke, it makes me rage)), the only time we used them was in a single view application that changed the alpha of a white background so it could be used as a flash light. This is how it was presented:

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

This is what I was attempting in my app:

In my ViewController.h files for EACH view:

...

@interface AppetizerViewController : UIViewController{
    NSUserDefaults *userDefaults;

    ...
}

@property(assign)NSUserDefaults *userDefaults;

Then when I clicked a button I wanted to save that value to 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];
} 

Then, since I had all of the constants for the NSUserDefault Keys in the header files of all of the views, I implemented all of the header files into the BillViewController like this and tried accessing them like this:

-(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];
} 

I'm sorry that what you guys tried to explain to me was completely over my head apparently and that my naming conventions are kinda f***ed, but I've been working on this for about 15 hours straight with few breaks and it's about 4:00am here in MN. How can I go about this? I'm sorry too that it might have to be kind of explicit on how to implement it.


回答1:


The good thing about NSUserDefaults is you don't need to instantiate it anywhere: it's already reachable from anywhere in your application. Just call [NSUserDefaults standardUserDefaults], and read or write to/from that object. Call synchronize on the object to make sure changes are stored on disk and then the next place you retrieve the standardUserDefaults object it will have the updated information.

Edit: Based on your above code, you could make the following changes to utilise the standard user defaults object:

  1. Get rid of your @property (assign) NSUserDefaults userDefaults; and your member variable NSUserDefaults userDefaults;
  2. Everywhere you want to read or write things to the user defaults, create a temporary variable: NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

The other way you could do it, which seems to be what you were trying to do, would be to set up the @property to be the standard user defaults object so it doesn't have to be retrieved by calling standardUserDefaults (since it seems you use it quite a bit, this is probably the way you should go).

To do it this way:

  1. Leave your @property, but set it to (retain) instead of (assign) (the standardUserDefaults object is autoreleased, so you need to hold on to it yourself). (optional) You can remove the NSUserDefaults userDefaults; line, since the @property creates this for you anyway
  2. When you initialise your view controller (or in viewDidLoad, like I'm doing here), set the userDefaults variable to the standard user defaults object:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.userDefaults = [NSUserDefaults standardUserDefaults];
    }
    
  3. Release the user defaults variable in the method corresponding to your initialisation method (dealloc for an init method, or viewDidUnload for viewDidLoad):

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



回答2:


There is nothing to "declare". Every time you say [NSUserDefaults standardUserDefaults] you are accessing the user defaults, no matter where you say it from. If you need to set default defaults (i.e. the initial values for certain keys), do it very very early in your program, e.g. in the app delegate's applicationDidFinishLaunching, by calling registerDefaults.




回答3:


If you are using NSUserDefaults a lot then it may be handy to create yourself a category to make sure you don't get typo's in your keys. For example say I constantly get and set values it would be handy to have the compiler do some checking to make sure I don't type the wrong keys and of course we all love autocomplete.

// 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

As a result in other classes where I use user defaults I can do something like:

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

Now all the keys are hidden and I interact with NSUserDefaults using a nicer API that is relevant to my app.



来源:https://stackoverflow.com/questions/8498213/how-to-implement-nsuserdefault-to-access-through-multiple-views

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!