0

这是使用全局变量之类的最干净的方法?通常,禁止使用全局变量,但我不知道从不同类访问 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"];

那会是一个解决方案吗?

4

2 回答 2

5

您不需要使用全局变量 - 您可以从项目中的任何类或对象访问用户默认值,如下所示:

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

只要在每次更改后同步 userdefaults,这种方式获取的数据是一致的。

于 2010-09-03T16:02:43.743 回答
1

全局变量不仅不被禁止,而且是 ANSI C 规范的必需部分,它是 Obj C 的子集。gcc 和 llvm 都完全支持全局变量。它们通常是传递不受保护的值的最小和最快的方法。

也就是说,显式使用全局变量很可能不是您问题的解决方案。您有一个非常适合 MVC 范例的问题。将所有 NSDefault 代码放入一个单例模型类(MVC 的 M)中,该类可以在首次访问时自行初始化(实现可能使用隐藏的全局),并将该对象附加到 appDelegate 可以很容易地从任何地方。然后将所有默认值读/写封装为该对象的属性。

于 2010-09-03T17:47:16.013 回答