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

Bro*_*olf 23 iphone delegates objective-c uiviewcontroller

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

我的第一个视图控制器(A)中有一个对象,其中包含我存储的所有应用程序数据(请忽略NSUserDefaults),当我按下按钮时,第二个视图控制器(B)需要访问该数据.我怎样才能以最好的方式实现这一目标?

小智 32

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

而不是像nevan所建议的那样引用app委托,另一种方法是为您的数据模型的视图控制器类(A和B)添加属性.

假设您想在视图控制器之间共享数据模型对象,则可以向每个控制器添加属性:

@interface AViewController : UIViewController {
    MyDataModel *model;
}

@property (nonatomic, retain) MyDataModel *model;

@end

@interface BViewController : UIViewController {
    MyDataModel *model;
}

@property (nonatomic, retain) MyDataModel *model;

@end
Run Code Online (Sandbox Code Playgroud)

初始化视图控制器时,可以将此属性设置为先前初始化的对象上下文.

您已经提到过标签栏控制器.如果您的视图控制器是通过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];
}
Run Code Online (Sandbox Code Playgroud)

不要忘记在视图控制器的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
Run Code Online (Sandbox Code Playgroud)

您可以从所有视图控制器访问此数据模型,其类似于以下内容:

MyDataModel *model = [MyDataModel sharedDataModel];
Run Code Online (Sandbox Code Playgroud)

另见关于单身人士的这一堆栈溢出讨论.


nev*_*ing 8

我见过的最常见的方法是在app delegate中设置你想要访问的东西,并在其他地方引用它,如下所示:

MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate]; 
myStuff = appDelegate.stuff;
Run Code Online (Sandbox Code Playgroud)

在app delegate中,设置一个stuff变量并像往常一样使用@property和@synthesize.

有人说这不是一个好方法,因为它与使用全局变量相同,但它很常见.


edo*_*lin 5

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

使用Apple示例中常见的水合物/脱水模式,使用仅使用数据库键填充对象的顶级加载方法也很有帮助.

应用代表中的典型用法很简单,

[[MyModel sharedModel] load];
Run Code Online (Sandbox Code Playgroud)

然后在视图控制器中:

NSArray *myThing1s = [[MyModel sharedModel] thing1s];
NSArray *myThing2s = [[MyModel sharedModel] thing2s];
Run Code Online (Sandbox Code Playgroud)

然后你可以迭代你的thing1s和thing2s,当你需要细节时,你可以打电话

[myThing1 hydrate];
Run Code Online (Sandbox Code Playgroud)

这将填充对象.

当然,您可能希望使用CoreData来管理从3.0开始的持久性.