iOS:数据文件的单例模式

时间:2013-09-29 00:21:55

标签: ios singleton

类名MyData在7个场景中都有75个以上的属性。

目前,我使用以下代码传递MyData文件的实例:

在SceneOne中

MyData *myData = [[MyData alloc]init];

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    UIViewController *destinationViewController = segue.destinationViewController;
    SceneTwo *sceneTwo = [destinationViewController isKindOfClass:[SceneTwo class]] ? (SceneTwo*)destinationViewController : nil;
    sceneTwo.myData = self.myData;
}

这允许我访问任何属性myData.anyProperty

当第7个场景被解除时,我设置myData = NULL,应用程序返回到SceneOne并初始化了一个新的MyData实例。

我正在尝试通过sharedInstance完成上述操作。

MyData.h

#import <foundation/Foundation.h>

@interface MyData : NSObject {

@property (nonatomic, retain) NSString *someProperty;
// 74 other properties

+ (id)sharedData;

@end

MyData.m

#import "MyData.h"

@implementation MyData

@synthesize someProperty;

+ (id)sharedData {
    static Mydata *sharedData = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedData = [[self alloc] init];
    });
    return sharedData;
}

@end

问题1:以上代码是否可以在任何场景中使用以下代码访问同一个实例:

 MyData *myData = [MyData sharedData];

问题2:我仍然可以myData.anyProperty访问这些文件吗?

问题3:如何触发MyData的新实例并删除当前实例?

问题4:我正在网上下载myData文件,该文件是MyData类的副本,但属性包含数据,我希望Singelton提供一个新实例,其中包含下载的数据文件,那将是什么代码? i.e myData = [newDownloadedFile copy];

问题5:使用Singleton Method Vs是否有优势?我目前的方法?

1 个答案:

答案 0 :(得分:2)

  1. 你没有。为什么你认为这是必要的?您可以改为向MyData添加reset方法吗?
  2. 您不应将单例模式与多实例用例混合使用。如果您真的需要单例,请考虑在数据集中添加其他图层。例如,您可能有本地数据远程数据配置。如果这是您想要的,您可能必须更改MyData的接口(标题)才能实现此目的。
  3. 单例是整个进程中类的单个实例。如果要从代码中的多个位置访问相同的数据集合,单个对象是实现此目的的一种方法。否则,您需要实例化一个对象并将其地址传递给所有感兴趣的类,以便它们每个都访问同一个实例。这是过于简单化,但我相信它可以解决你的问题。
  4. 关于您对3号的评论,如果您有单身,如果您不再需要在一个地方使用数据,则不希望重置整个应用的数据。因此,请考虑可能产生的影响。如果您不再需要MyData对象,则不要再使用它了。 Singleton对象通常在应用程序的生命周期内持久存在,因此释放/处置对象并不常见。

    对于4号,假设您目前有一个名为player的属性,其方法声明如下:

    - (Player *)currentPlayer;
    

    如果您有多个可用配置,则可以在方法界面和实现中添加一个参数,如下所示:

    - (Player *)currentPlayerForConfiguration:(NSInteger)configuration;
    

    您可以决定使用数字,字符串或其他内容来区分数据的不同配置。如果你使用数字,0可以是本地的,1可以是远程的,2可以是(例如,首先检查本地数据,如果没有,则检查远程)。如果您只有两个选项,则可以使用BOOL并定义您的方法:

    - (Player *)currentPlayerUsingLocalData:(BOOL)useLocalData;