Как можно избежать нескольких экземпляров одного и того же объекта модели в iOS (MVC) - PullRequest
3 голосов
/ 19 января 2012

Я работаю над проектом, в котором у меня есть модель, которая используется несколькими различными представлениями и, следовательно, контроллерами представления. Эти контроллеры представления не знают о существовании друг друга и не имеют никакого отношения друг к другу. Это означает, что у меня есть модель * в каждом из контроллеров представления, и когда представления загружаются, я выделяю модель в каждом классе и указываю на нее указатели. Или кратко: я выделяю свою модель n раз в n классах, которые ее используют, что, по моему мнению, является пустой тратой памяти (не то, чтобы у меня не хватало памяти, но я думаю, что это плохая практика).

Есть ли способ в iOS, где я (при сохранении хорошей практики MVC) могу создать и использовать один и тот же экземпляр моей модели? Обычно я программировал на с ++, где передавал ссылку на модель конструктору каждого класса, который должен знать модель. Пример (c ++):

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

Вместо этого я делаю следующее в каждом классе, использующем мою модель (target-c):

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

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

Я не хочу делать все модели одноэлементными объектами, и в этом конкретном проекте я думаю, что использование шаблона наблюдателя было бы излишним.

Итак, мой вопрос: как я могу достичь этого и возможно ли это вообще?

Ответы [ 4 ]

3 голосов
/ 19 января 2012

Вы можете написать свой собственный инициализатор, который берет указатель на модель.

в файле .h вашего контроллера A и B

@property(nonatomic,assign)Model* myModel;

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

в файле .m вашего контроллера A и B

@synthesize myModel;

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

    if(self){
        self.mymodel = model;

    }

    return self;
}

EDIT

Если вы используете IB, вы должны написать свой инициализатор следующим образом:

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

        self.mymodel = model;
    }
    return self;
}
2 голосов
/ 19 января 2012

Я думаю, вам нужно использовать шаблон singleton

Тривиальная реализация ведьмы выглядит такYourClass.m:

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


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

Хорошая статья об этом ссылка на яблоко

1 голос
/ 19 января 2012

У вас правильная идея: предоставить модель контроллерам представления, которые нуждаются в ней при их создании; не ищите в синглтоне или другом глобальном центре нужную им информацию.

Поскольку вы спрашивали о контроллерах представления и поскольку они часто создаются из файлов .xib или раскадровки, вам, возможно, придется немного изменить свой подход. Вместо предоставления ссылки на модель в инициализаторе, вы можете просто добавить свойство, которое сохраняет ссылку на модель для каждого из ваших контроллеров представления. Объект, который отвечает за создание контроллера представления, может затем предоставить модель после того, как контроллер был создан. Например, метод -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;

Большим преимуществом здесь по сравнению с одноэлементным подходом является то, что ваши контроллеры представления не принимают ничего об остальной части приложения. Каждый из них будет использовать любую модель, которую вы им дадите. Это делает ваш код чище, легче управлять, легче переставлять и т. Д.

0 голосов
/ 19 января 2012

Создав объекты модели, вы можете хранить эти экземпляры в глобальном словаре с ключом, в каком-то классе, у которого есть только один экземпляр, то есть в одиночном.Когда контроллеру представления нужна эта модель, он может попросить этот синглтон предоставить ему необходимые данные, предоставив ключ словаря.

Или вы можете хранить ваши данные в coredata и извлекать их оттуда всякий раз, когда вам это нужно от контроллера представления.Таким образом, вы также достигнете настойчивости, если вам это нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...