Как определить глобальную переменную типа NSUserDefaults и инициализировать значение? - PullRequest
0 голосов
/ 03 сентября 2010

Какой самый чистый способ использовать что-то вроде глобальной переменной? Обычно использование глобальной переменной запрещено, но я не знаю лучшего решения для доступа к NSUserDefaults из разных классов.

Я немного читаю и придумываю это. Я определяю файл Contants.h и файл Constants.m и включаю их везде, где мне нужно.

 //Constants.h
 #import <Foundation/Foundation.h>


 @interface Constants : NSObject {
  extern NSUserDefaults *settings;
 }

 @end

.

 //Constants.m
 @implementation Constants

 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"plist"];
 NSDictionary *settingsDict = [NSDictionary dictionaryWithContentsOfFile:filePath];
 [[NSUserDefaults standardUserDefaults] registerDefaults:settingsDict];
 NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];

 @end

Проблема здесь в том, что я хочу инициализировать значение моей константой. У меня нет метода в Constants.m. Так что мои вспомогательные переменные также будут глобальными?

Стоит упомянуть одну вещь: я думаю, что глобальная переменная также должна быть выпущена?

Спасибо за вашу помощь!

Edit:

@ hotpaw2:

AppBundleSingleton.h:

#import <Foundation/Foundation.h>


@interface AppBundleSingleton : NSObject {

}

+ (AppBundleSingleton *)sharedAppBundleSingleton;

@end

AppBundleSingleton.m:

#import "AppBundleSingleton.h"


static AppBundleSingleton *sharedAppBundleSingleton = nil;


@implementation AppBundleSingleton

#pragma mark -
#pragma mark Singleton methods

+ (AppBundleSingleton *)sharedAppBundleSingleton {
    @synchronized(self) {
        if (sharedAppBundleSingleton == nil) {
            sharedAppBundleSingleton = [[self alloc] init];
        }
    }
    return sharedAppBundleSingleton;
}

+ (id)allocWithZone:(NSZone *)zone {
    @synchronized(self) {
        if (sharedAppBundleSingleton == nil) {
            sharedAppBundleSingleton = [super allocWithZone:zone];
            return sharedAppBundleSingleton;  // assignment and return on first allocation
        }
    }
    return nil;  // on subsequent allocation attempts return nil
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (id)retain {
    return self;
}

- (NSUInteger)retainCount {
    return NSUIntegerMax;  //denotes an object that cannot be released
}

- (void)release {
    //do nothing
}

- (id)autorelease {
    return self;
}

-(id)init {
    self = [super init];
    sharedAppBundleSingleton = self;
    // Initialization code here
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"plist"];
    NSDictionary *settingsDict = [NSDictionary dictionaryWithContentsOfFile:filePath];
    [[NSUserDefaults standardUserDefaults] registerDefaults:settingsDict];

    return self;
}

@end

В моем AppDelegate.m у меня есть следующее:

// ...
#include "AppBundleSingleton.h"


@implementation MyAppDelegate

// ...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.

    // Add the navigation controller's view to the window and display.
    [window addSubview:navigationController.view];
    [window makeKeyAndVisible];

    [AppBundleSingleton sharedAppBundleSingleton];

    return YES;
}
// ...
@end

В моем ViewController я запрашиваю значения:

NSString *myString = [[NSUserDefaults standardUserDefaults] stringForKey:@"myKeyforString"];

Это было бы решением?

Ответы [ 2 ]

5 голосов
/ 03 сентября 2010

Вам не нужно использовать глобальные переменные - вы можете получить доступ к пользовательским ошибкам из любого класса или объекта в вашем проекте, например:

BOOL foo = [[NSUserDefaults standardUserDefaults] boolForKey:@"bar"];

Пока вы синхронизируете пользовательские ошибки после каждого внесенного вами измененияданные, полученные таким образом, согласованы.

1 голос
/ 03 сентября 2010

Глобальные переменные не только НЕ запрещены, но и являются обязательной частью спецификации ANSI C, которая является подмножеством Obj C. И gcc, и llvm полностью поддерживают глобальные переменные.Они часто являются самым маленьким и быстрым способом передачи незащищенных значений.

При этом явное использование глобальных переменных, скорее всего, не является решением вашей проблемы.У вас есть проблема, вполне подходящая для парадигмы MVC.Поместите весь свой код NSDefault в класс одноэлементной модели (M из MVC), который может самоинициализироваться при первом доступе (реализация может использовать скрытый глобальный объект), и прикрепите этот объект к appDelegate, где его легко получить изв любом месте.Затем инкапсулируйте все значения по умолчанию для чтения / записи в качестве свойств этого объекта.

...