плохая идея использовать NSUserDefaults как глобальную переменную экземпляра? - PullRequest
4 голосов
/ 20 августа 2011

У меня есть приложение, которое при загрузке главного домашнего экрана проверяет наличие обновлений синхронизации в фоновом режиме. При медленном соединении или при быстром перемещении пользователя по приложению куча этих запросов может сложиться в фоновом режиме. Чтобы предотвратить это, я хочу реализовать переменную BOOL, в которой я переключаю YES или NO, чтобы предотвратить отправку нескольких запросов на проверку синхронизации.

Таким образом, мой код будет выглядеть примерно так при запуске запроса:

 NSUserDefaults *d = [NSUserDefaults standardUserDefaults];
 NSString *key = [NSString stringWithFormat:kVarAllowSyncRequest, aManufacturerID];
 [d setBool:NO forKey:key];

Я знаю, что это будет работать, но это будет вызываться сотни раз во время использования моего приложения - это то, что мне даже нужно беспокоиться?

Есть ли лучший подход к этому?

Ответы [ 3 ]

3 голосов
/ 20 августа 2011

Пользовательские настройки по умолчанию - это хорошее место для размещения предпочтений и информации, которая не изменяется или к которой требуется доступ более двух или трех раз за сеанс.Доступ к настройкам по умолчанию означает удар по диску, который идет медленно;Вы не хотите использовать его для чего-то вроде проверки флага много раз в минуту.

Делегат приложения - это удобное место для хранения информации, которая действительно должна быть доступна для многих объектов в вашем приложении, поскольку онавсегда доступен через [[UIApplication sharedApplication] delegate], но вы должны тщательно продумать дизайн своего приложения, прежде чем взвешивать этот объект большим количеством иваров только потому, что это кажется удобным.

Предположительно, существует только один объект, возможно, контроллер представления,который отвечает за отправку этих запросов.Это место, чтобы поставить флаг.Из вашего описания не похоже, что вам вообще нужна глобальная переменная приложения.Флаг используется только объектом, который инициирует запрос, и поэтому это единственный объект, который должен знать о нем.Флаг может быть иваром.

Если на самом деле у вас есть класс , у которого может быть много экземпляров, каждый из которых будет отправлять запрос, тогда правильное решение будетиметь флаг уровня класса, к которому имеет доступ любой экземпляр.Это просто.В вашем файле реализации объявите переменную для хранения флага:

// RequestMaker.m

#import "RequestMaker.h"

static BOOL allowSyncRequest = YES;

@implementation RequestMaker
// etc.

Объявлено static, чтобы сделать его видимым только в этом «модуле компиляции» (в общем, в этом файле).

Затем вы создаете метод класса каждый для установки и получения этого флага:

+ (BOOL) allowSyncRequest {
    return allowSyncRequest;
}

+ (void) setAllowSyncRequest: (BOOL)b {
    allowSyncRequest = b;
}

Теперь каждый раз, когда один из ваших RequestMaker экземпляров хочет запустить запрос, он должен проверять флаг;если это YES, тогда вы можете отключить флаг и запустить запрос.Вам также необходимо убедиться, что сбросил флаг после завершения запроса.

(Все это предполагает, что вы явно не работаете в разных потоках для своих запросов. Если вы , то вам следует изучить очереди GCD и, возможно, семафоры.Есть отличный набор рецензий Майка Эша , которые доставят удовольствие чтению, даже если вы не хотите использовать GCD.)

3 голосов
/ 20 августа 2011

Да, это будет медленно!

Либо вставьте свой AppDelegate, либо создайте для него синглтон http://blog.mugunthkumar.com/coding/objective-c-singleton-template-for-xcode-4/

0 голосов
/ 20 августа 2011

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

Самым простым для реализации решения глобальных переменных является добавление свойств к одноэлементному классу, который уже доступен вам - вашему делегату приложения! Вот код, который я обычно использую в контроллерах представления, которым часто требуется доступ к делегату приложения:

// read-only property to return my app delegate
- (MyAppDelegate*)appDelegate {
return (MyAppDelegate*)[[UIApplication sharedApplication] delegate] ;
}

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

self.appDelegate.allowSyncRequest = NO;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...