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

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

我有一个对象在我的第一个视图控制器(A),其中包含我所有存储的应用程序数据(请忽略NSUserDefaults为此)需要由第二个视图控制器(B)访问时,我按下它的一个button。 我怎样才能以最好的方式做到这一点?

你有一个select是声明你的date模型作为你的应用程序委托(如其他评论者所述)的实例variables。

而不是像nevan所build议的那样引用应用程序委托,而是为你的数据模型添加一个属性到你的视图控制器类(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: method中设置这些参数:

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

另请参阅关于单例的堆栈溢出讨论。

我见过的最常见的方法是在应用程序委托中设置你想要访问的东西,并在其他地方引用它:

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

在应用程序委托中,设置一个东西variables,像往常一样使用@property和@synthesize。

有人说这不是一个好的方法,因为它和使用全局variables是一样的,但是这很常见。

我喜欢创build一个单独的顶级Model类,并包含我可能需要的所有元素。

给它一个顶级的加载方法是很有帮助的,它只用db键填充对象,使用Apple例子中常见的水合物/脱水模式。

应用程序委托中的典型用法很简单,

 [[MyModel sharedModel] load]; 

然后在视图控制器中:

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

然后你可以迭代你的thing1s和thing2s,当你需要细节的时候,你可以调用

 [myThing1 hydrate]; 

这将填充对象。

当然,你可能想使用CoreData从3.0开始pipe理持久性。

我总是创build一个名为DataModel的特殊对象,并使用它的单例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.happlication-prefix.pch

这样我就可以通过调用来从应用程序的任何地方访问我的数据

 [DataModel sharedModel] 

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

在这种情况下,C将是MVC中的M.

为每个ViewController添加以下声明:

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