如何在iOS(MVC)中避免同一模型对象的多个实例

时间:2012-01-19 15:53:33

标签: iphone ios model-view-controller model

我正在开发一个项目,其中我有一个模型,由几个不同的视图使用,从而视图控制器。这些观察者不了解彼此的存在,也没有彼此的任何关系。这意味着我在每个viewcontrollers中都有一个模型*,当加载视图时,我在每个类中分配模型并使指针指向它。或简称:我在使用它的n个类中分配我的模型n次,我认为这是浪费内存(不是说我会耗尽内存,但我认为这是不好的做法)。

iOS中是否存在一种方式(我仍然保持良好的MVC实践)能够创建和使用我的模型的相同实例?通常我一直在用c ++编程,我将模型的引用传递给应该知道模型的每个类的构造函数。示例(c ++):

// Let to classes know of the same model object
MyModel model;
ControllerA myControllerA(&model);
ControllerB myControllerB(&model);

相反,我在每个使用我的模型的类(objective-c)中执行以下操作:

// ControllerA
model = [[MyModel alloc] init];

// Controller B
model = [[MyModel alloc] init];

我不想制作所有模型单例对象,在这个特定的项目中,我认为使用观察者模式会有点过分。

所以,我的问题是:我怎样才能做到这一点,甚至可能?

4 个答案:

答案 0 :(得分:3)

您可以编写自己的初始化程序,该指针指向模型。

在ControllerA和B的.h文件中

@property(nonatomic,assign)Model* myModel;

-(id)initWithModel:(Model*)model;

在ControllerA和B的.m文件中

@synthesize myModel;

-(id)initWithModel:(Model*)model{
    self = [super init];

    if(self){
        self.mymodel = model;

    }

    return self;
}

修改

如果您正在使用IB,您将按以下方式编写启动器:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil model:(Model*)model
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

        self.mymodel = model;
    }
    return self;
}

答案 1 :(得分:2)

我认为,你需要使用单身模式

女巫的琐碎实施看起来像这样

YourClass.h

+ (id)sharedInstance;

YourClass.m:

+(id)singleton {
    static dispatch_once_t pred;
    static MyClass *shared = nil;


    dispatch_once(&pred, ^{
     shared = [[MyClass alloc] init];
    });
    return shared;
}

关于它的好文章 apple reference

答案 2 :(得分:1)

您有正确的想法:在创建模型时将模型提供给需要它的视图控制器;不要去寻找单身人士或其他全球所需的信息。

由于您询问了视图控制器,并且由于这些控制器通常是从.xib或storyboard文件实例化的,因此您可能需要稍微调整一下。您可以简单地向每个视图控制器添加一个存储模型引用的属性,而不是在初始化程序中提供对模型的引用。然后,负责创建视图控制器的对象可以在创建控制器之后提供模型。例如,在创建根视图控制器之后,将调用您的app delegate的-applicationDidFinishLaunchingWithOptions:方法,现在是设置模型并将根视图控制器指向它的好时机:

-applicationDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // set up the model
    self.model = [[MyModel alloc] initWithFile:...];

    // get the root controller and give it a pointer to the model
    MyFirstViewController *firstController = self.window.rootViewController;
    firstController.model = model;
}

然后,根视图控制器可以将模型传递给它创建的其他视图控制器。如果您有基于选项卡的应用程序,则应用程序委托可能会将模型传递给选项卡控制器下的所有视图控制器。在这种情况下,您的选项卡控制器将成为窗口的根视图控制器,您可以像这样访问您的视图控制器:

NSArray *controllers = self.window.rootViewController.viewControllers;

这种单例方法的一大优势是你的视图控制器不会假设应用程序的其余部分。他们每个人都会使用你给他们的任何模型。这使您的代码更清晰,更易于管理,更容易重新排列等等。

答案 3 :(得分:0)

创建模型对象后,可以将这些实例存储在带有键的全局字典中,在某些类中只有一个实例,即单例。当视图控制器需要此模型时,它可以通过提供字典键来要求此单例为其提供所需的数据。

或者您可以将数据存储在coredata中,并在需要时从视图控制器中获取数据。这样,如果需要,你也可以实现持久性。