Подтвердить что ты не робот

Как я могу совместно использовать объект между UIViewControllers на iPhone?

Мое приложение - это приложение панели вкладок с отдельным контроллером представления для каждой вкладки.

У меня есть объект в моем первом контроллере представления (A), который содержит все мои данные хранимых приложений (просьба игнорировать NSUserDefaults для этого), к которым должен быть обращен второй контроллер представления (B), когда я нажимаю на него кнопку. Как я могу достичь этого наилучшим образом?

4b9b3361

Ответ 1

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

Вместо ссылки на делегат приложения, предложенный nevan, альтернативой является добавление свойства к вашим классам контроллера представления (A и B) для вашей модели данных.

Предположим, вы хотите поделиться объектом модели данных между контроллерами представлений, которые вы можете добавить к каждому из них:

@interface AViewController : UIViewController {
    MyDataModel *model;
}

@property (nonatomic, retain) MyDataModel *model;

@end

@interface BViewController : UIViewController {
    MyDataModel *model;
}

@property (nonatomic, retain) MyDataModel *model;

@end

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

Вы упомянули контроллер панели вкладок. Если ваши контроллеры просмотра подключены через IB, все, что вам нужно сделать, это установить эти параметры в своем делетететом делегирования applicationDidFinishLaunching:, прежде чем отобразится контроллер панели вкладок:

@interface MyAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate>
{

    MyDataModel *model;
    AViewController *aViewController;
    BViewController *bViewController;
    ...
}

@property (retain) IBOutlet AViewController *aViewController;
@property (retain) IBOutlet BViewController *aViewController;

@end

@implementation MyAppDelegate

...

- (void)applicationDidFinishLaunching:(UIApplication *)application
{
...

    aViewController.model = model;

    bViewController.model = model;

    [window addSubview:tabBarController.view];
    [window makeKeyAndVisible];
}

Не забудьте выпустить модель в вашем контроллере вида dealloc.


Альтернативой является использование одноэлементного объекта. Простой пример синглтона:

@interface MyDataModel : NSObject
{
}

+ (MyDataModel *) sharedDataModel;

@end

@implementation MyDataModel

static MyDataModel *sharedDataModel = nil;

+ (MyDataModel *) sharedDataModel
{

    @synchronized(self)
    {
        if (sharedDataModel == nil)
        {
            sharedDataModel = [[MyDataModel alloc] init];
        }
    }
    return sharedDataModel;
}

@end

Вы можете получить доступ к этой модели данных со всех контроллеров вашего вида с помощью примерно следующего:

MyDataModel *model = [MyDataModel sharedDataModel];

См. также

Ответ 2

Самый распространенный способ, которым я это видел, - настроить то, что вы хотите получить в делегате приложения, и ссылаться на него в других местах:

MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate]; 
myStuff = appDelegate.stuff;

В делегате приложения настройте переменную stuff и используйте как обычно, @property и @synthesize.

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

Ответ 3

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

Полезно также дать ему метод загрузки верхнего уровня, который заполняет объекты только с помощью клавиш db, используя шаблон гидрата/дегидрата, распространенный в примерах Apple.

Типичное использование в делегате приложения было бы просто,

[[MyModel sharedModel] load];

И затем в контроллере вида:

NSArray *myThing1s = [[MyModel sharedModel] thing1s];
NSArray *myThing2s = [[MyModel sharedModel] thing2s];

Затем вы можете перебирать свои вещи и вещи2, а когда вам нужны детали, вы можете просто позвонить

[myThing1 hydrate];

который заполнит объект.

Конечно, вы, вероятно, захотите использовать CoreData для управления персистентностью начиная с 3.0.

Ответ 4

Я всегда создаю специальный объект с именем DataModel и использую его singleton sharedInstance.

И этот объект затем содержит все связанные с приложением данные. Нет необходимости в доступе к страшному appDelegate.

DataModel.h

#import <Foundation/Foundation.h>

@class MyClass1, MyClass2;

@interface DataModel : NSObject

@property (copy, nonatomic) NSString *aString;
@property (assign) BOOL aBool;

@property (strong) MyClass1 *myObject1;
@property (strong) MyClass2 *myObject2;

+ (DataModel *)sharedModel;

@end

DataModel.m

#import "DataModel.h"
#import "Class1.h"
#import "Class2.h"

@implementation DataModel

- (id) init
{
    self = [super init];
    if (self)
    {
        _myObject1 = [[MyClass1 alloc] init];
        _myObject2 = [[MyClass2 alloc] init];
        aBool = NO;
        aString = nil;
    }
    return self;
}

+ (DataModel *)sharedModel
{
    static DataModel *_sharedModel = nil;
    static dispatch_once_t onceSecurePredicate;
    dispatch_once(&onceSecurePredicate,^
                  {
                      _sharedModel = [[self alloc] init];
                  });

    return _sharedModel;
}

@end

И (потому что я ленив) я положил DataModel.h в application-prefix.pch.

Таким образом, я могу получить доступ к своим данным из любого места приложения, просто позвонив

[DataModel sharedModel]

Ответ 5

Оба контроллера представления должны ссылаться на третий объект (C) как на свой источник данных; этот объект (C) содержит все сохраненные данные приложения.

C будет в этом случае M в MVC.

Добавьте к каждому из ваших ViewControllers следующие объявления:

// SomeViewController.h
// Before @interface

@class MyDataSource;

// In the interface

IBOutlet MyDataSource *datasource;
@property(retain) IBOutlet MyDataSource *datasource;