2010-09-03 46 views
0

這是使用類似全局變量的最簡潔的方法嗎?通常情況下,禁止使用全局變量,但我不知道從不同類訪問NSUserDefaults的更好的解決方案。如何定義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中沒有方法。所以我的幫助變量也將是全局變量?

有一點要提到:我認爲全局變量也必須被釋放?

感謝您的幫助!

編輯:

@ 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"]; 

那會是一個解決辦法?

回答

1

全局變量不僅被禁止,而且是ANSI C規範的必需部分,它是Obj C的一個子集。gcc和llvm都完全支持全局變量。它們通常是傳遞未受保護價值的最小和最快的方式。

也就是說,顯式使用全局變量很可能不是解決您的問題的方法。你有一個非常適合MVC範式的問題。將所有的NSDefault代碼放入一個單例模型類(MVC的M)中,該類可以在第一次訪問時自我初始化(實現可以使用隱藏的全局),並將該對象附加到appDelegate,從而可以輕鬆地從任何地方。然後將所有默認值讀取/寫入封裝爲該對象的屬性。

+0

我編輯了我的問題。我現在用init方法創建了一個Singleton,它從plist文件初始化我的NSUserDefaults。我不再需要一個全局變量。我在didFinishLaunchingWithOptions中訪問我的Singleton實例。是對的嗎?它到目前爲止工作正常,但你提到「在appDidFinishLaunching之前可能會調用一些需要默認初始配置的視圖」。如何將我的單例附加到appDelegate而不使用didFinishLaunching?我直接調用NSUserDefaults,所以從任何地方都可以獲得。 – testing 2010-09-06 11:05:32

+0

自我初始化過程是通過調用sharedAppBundleSingleton和寫入的init方法完成的。封裝的東西是什麼意思?我需要這些屬性嗎?我已經在Singleton的init方法中初始化了我的默認值。 – testing 2010-09-06 11:10:57

+0

這裏有人嗎? – testing 2010-09-08 07:36:12

5

你並不需要使用全局變量 - 你可以從任何類或對象訪問您的項目中userdefaults是這樣的:當你每一步更改您做出同步userdefaults

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

長,以這種方式獲取的數據是一致的。

+0

我想用這個NSString初始化我的NSUserDefaults * filePath = [[NSBundle mainBundle] pathForResource:@「Settings」ofType:@「plist」]; NSDictionary * settingsDict = [NSDictionary dictionaryWithContentsOfFile:filePath]; [[NSUserDefaults standardUserDefaults] registerDefaults:settingsDict]; 我該怎麼做? – testing 2010-09-03 16:26:35

+0

@在你測試appDidFinishLaunching:方法 – 2010-09-03 16:42:30

+0

appDidFinishLaunching可能會也可能不會。某些需要默認初始配置的視圖可能會在appDidFinishLaunching之前調用。 – hotpaw2 2010-09-03 17:38:53