将全局字典添加到AppDelegate vs singleton类

时间:2013-01-07 16:07:33

标签: iphone ios

我看到建议在单例类而不是AppDelegate中定义全局数据(即NSArray或NSDictionary)。

为什么会这样?

谢谢, 弗兰克

4 个答案:

答案 0 :(得分:2)

AppDelegate特定于您正在处理的项目。如果您决定启动正在使用的应用程序的新版本,或者(更有可能)将其从iOS等移植到Mac ...

AppDelegate将保持原状。

通过将这样的全局信息放入单例中,您可以创建一个独立于正在运行的应用程序的类。

此外,你最好在AppDelegate中保留App特定的东西(比如applicationWillEnterBackground),并且不想用其他东西堵塞它。

答案 1 :(得分:1)

如果您打算为代码创建单元测试,则应避免使用全局单例,因为它们会使代码更难以测试。同样,根据我的经验,对于这些值具有公开的NSArrayNSDictionary,代码可以很容易地快速获得错误。

我发现有用的设计模式实际上是使用您想要的所有属性来创建配置或全局值对象。通常,此类包装NSArrayNSDictionary,您可以从plist文件加载它。此对象可以在AppDelegate中实例化,然后在实例化视图控制器和其他对象时传递。这更容易测试,因为您可以在测试中轻松模拟配置对象。

从plist文件加载时这种配置对象的外观示例:

界面:

@interface ConfigManager : NSObject {

}
@property (readonly) NSString* masterUser;
@property (readonly) UIImage* masterUserImage;

@end

然后在.m

@interface ConfigManager ()
@property (strong) NSDictionary* configDict;

@end

@implementation ConfigManager


-(id)init {

    self = [super init];

    if ( self ) {
        NSString *pathStr = [[NSBundle mainBundle] pathForResource:@"AppConfig" ofType:@"plist"];
        NSData *plistData = [NSData dataWithContentsOfFile:pathStr];
        NSString *error = nil;
        NSPropertyListFormat format;

        self.configDict = (NSDictionary*)[NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];

        if(nil == self.configDict || nil != error ) {
            NSLog(@"%@",error);

            return nil;
        }   

    }

    return self;
}

-(NSString*)masterUser {
    return [self.configDict objectForKey:@"masterUser"];
}

-(UIImage*)masterUserImage {
    NSString* imageName = [self.configDict objectForKey:@"masterUserImage"];

    return [UIImage imageNamed:imageName];
}

当然,改变对象的属性以满足您的需求。这种方法的好处在于,您可以实现一次处理应用程序的全局配置所需的公共代码,例如加载图像。这有助于防止因在代码库中反复复制相同代码而导致的一类常见错误。

答案 2 :(得分:0)

这样你就不会混淆AppDelegate。大多数AppDelegates就像是全球数据的厨房水槽。一切都被扔进那里。使用单例(如果是ARC,只使用常规类)将实际全局数据与基本AppDelegate函数分开。

答案 3 :(得分:0)

我不认为Singeltons是一个很好的解决方案,我更喜欢应用程序全局变量更好地保存在一个诚实的全局可访问类中,如AppDelegate。

18年前,一个单例构造被认为是一种设计模式,但后来Erich Gamma意识到,将这种模式添加到他的书“设计模式 - 可重用面向对象软件的元素”中是一个坏主意。

今天在像Java这样的现代语言中,Singeltons是邪恶的,因为一旦它们被初始化就无法删除它们,因此会严重干扰单元测试。所以至少在java中,使用单例时更容易出现糟糕的设计。老实说,如果你有一个全局对象,那么就这样处理它,不要把它隐藏在伪全局元素后面。

然而,Objective-C没有虚拟机,因此Singletons可能不会影响单元测试,(我对此不确定)。
如果它们不影响单元测试,单元有时候很方便使用,如[NSFileManager defaultManager] 但我不会将NSArray或词典存储到单身人士中。