如何在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.h
在application-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;