Как реализовать NSUserDefault для доступа через несколько представлений - PullRequest
3 голосов
/ 14 декабря 2011

Я пытаюсь обмениваться строками и целыми числами в нескольких представлениях для финального проекта на начальном курсе разработки для iOS, около 50, и мне интересно, как бы я поступил так ... Я знаю, что парадигма MVC лучше, но мы не добрались до очень продвинутых вещей, особенно основных данных. Я думал об использовании NSUserDefaults, я знаю, что это неправильно, но это приложение не должно быть невероятно быстрым, и я думаю, что это будет самый простой способ для меня. У меня вопрос, где и как я объявил бы объект NSUserDefault, который я буду использовать? Единственное время в классе, которое мы использовали, было в одном представлении. Если я объявлю его в первом загруженном представлении, я знаю, что могу получить к нему доступ с помощью других представлений, но нужно ли мне импортировать файл заголовка первого представления в каждое из остальных или он будет доступен независимо от этого?


Обновление


Поэтому я подумал, что постараюсь упростить ситуацию, сделав NSUserDefaults свойством во всех ViewControllers. Затем, чтобы попытаться вернуть значения, я реализовал заголовки от каждого из ViewControllers в представлении, которое должно получить доступ к данным, хранящимся в NSUserDefaults (которое также имеет свойство NSUserDefault). Приложение работает ужасно, пока я не дохожу до этого экрана, и ничего не обновляется. Я уверен, что моя ошибка лежит где-то в том, как я реализовал NSUserDefaults, но я не уверен, как это сделать правильно. Когда мы просмотрели их в классе (на самом деле это целенаправленное исследование с «Разработка приложения iPhone для Сэма: научи себя 24 часа в сутки» (блин, это меня бесит), единственный раз, когда мы использовали их, было в одном приложении, которое изменило альфа белого фона, чтобы его можно было использовать в качестве фонарика. Вот как это было представлено:

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:00 утра здесь, в Миннесоте. Как я могу пойти по этому поводу? Мне тоже жаль, что, возможно, должно быть что-то вроде того, как это реализовать.

Ответы [ 3 ]

7 голосов
/ 14 декабря 2011

Хорошая вещь о NSUserDefaults в том, что вам не нужно создавать его где-либо: он уже доступен из любого места в вашем приложении. Просто позвоните [NSUserDefaults standardUserDefaults] и читайте или пишите в / из этого объекта. Вызовите synchronize объекта, чтобы убедиться, что изменения сохранены на диске, а затем при следующем получении объекта standardUserDefaults у него будет обновленная информация.

Редактировать: На основе приведенного выше кода вы можете внести следующие изменения, чтобы использовать стандартный объект по умолчанию для пользователя:

  1. Избавьтесь от @property (assign) NSUserDefaults userDefaults; и переменной члена NSUserDefaults userDefaults;
  2. Везде, где вы хотите прочитать или записать что-то для пользователя по умолчанию, создайте временную переменную: NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

Другой способ, которым вы могли бы сделать это, что, похоже, и было то, что вы пытались сделать, - это установить @property в качестве стандартного объекта по умолчанию для пользователя, чтобы его не нужно было вызывать с помощью вызова standardUserDefaults (так как кажется, что вы используете его совсем немного, это, вероятно, вам следует идти).

Чтобы сделать это так:

  1. Оставьте свой @property, но установите его (retain) вместо (assign) (объект standardUserDefaults равен autorelease d, так что вам нужно держаться за него самостоятельно). (необязательно) Вы можете удалить строку NSUserDefaults userDefaults;, поскольку @property все равно создаст ее для вас
  2. Когда вы инициализируете свой контроллер вида (или в viewDidLoad, как я здесь делаю), установите переменную userDefaults для стандартного объекта по умолчанию пользователя:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.userDefaults = [NSUserDefaults standardUserDefaults];
    }
    
  3. Отпустите переменную по умолчанию пользователя в методе, соответствующем вашему методу инициализации (dealloc для метода init или viewDidUnload для viewDidLoad):

    - (void)viewDidUnload
    {
        self.userDefaults = nil;
    }
    
2 голосов
/ 14 декабря 2011

Если вы используете 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

Теперь все ключи скрыты, и я взаимодействую с NSUserDefaults, используя более приятный API, соответствующий моему приложению.

2 голосов
/ 14 декабря 2011

Нечего "декларировать". Каждый раз, когда вы говорите [NSUserDefaults standardUserDefaults], вы получаете доступ к пользовательским настройкам по умолчанию, независимо от того, откуда вы это говорите. Если вам нужно установить значения по умолчанию (то есть начальные значения для определенных ключей), сделайте это очень рано в вашей программе, например, в applicationDidFinishLaunching делегата приложения, вызвав registerDefaults.

...