代码之家  ›  专栏  ›  技术社区  ›  Brock Woolf

如何在iPhone上的UIViewController之间共享对象?

  •  23
  • Brock Woolf  · 技术社区  · 16 年前

    我的应用程序是一个选项卡栏应用程序,每个选项卡都有一个单独的视图控制器。

    我在第一个视图控制器(A)中有一个对象,其中包含我存储的所有应用程序数据(请忽略NSUserDefaults),当我按下第二个视图控制器(B)上的按钮时,它需要被第二个视图控制器(B)访问。如何以最佳方式实现这一点?

    5 回复  |  直到 13 年前
        1
  •  31
  •   Community Mohan Dere    9 年前

    您可以选择将日期模型声明为应用程序委托的实例变量(如其他评论员所述)。

    与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];
    

    另见 this 关于单例的堆栈溢出讨论。

        2
  •  8
  •   nevan king    16 年前

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

    有人说这不是一个好方法,因为它与使用全局变量是一样的,但它非常常见。

        3
  •  5
  •   edoloughlin    16 年前

    我喜欢创建一个顶级模型类,它是一个单例,包含我可能需要的所有元素。

    使用Apple示例中常见的水合物/脱水模式,为它提供一种顶层加载方法,只使用db键填充对象,这也很有帮助。

    应用程序委托中的典型用法是,

    [[MyModel sharedModel] load];
    

    然后在视图控制器中:

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

    然后你可以迭代你的东西1和东西2,当你需要详细信息时,你可以打电话

    [myThing1 hydrate];
    

        4
  •  3
  •   Rok Jarc    13 年前

    我总是创建一个名为 DataModel 使用它的singleton sharedInstance

    然后这个对象保存所有与应用程序相关的数据。无需访问 appDelegate .

    数据模型

    #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
  •  0
  •   Williham Totland    16 年前

    两个视图控制器都应引用第三个对象(C)作为其数据源;此对象(C)包含所有存储的应用程序数据。

    向每个ViewController添加以下声明:

    // SomeViewController.h
    // Before @interface
    
    @class MyDataSource;
    
    // In the interface
    
    IBOutlet MyDataSource *datasource;
    @property(retain) IBOutlet MyDataSource *datasource;
    
    推荐文章