无法在iOS 6中的子视图控制器之间传递指针

时间:2013-04-14 22:18:00

标签: pointers ios6

我的问题在于iOS 6标签式应用程序。我正在进行的工作有5个选项卡,有几个选项卡是到其他视图控制器的网关。大多数页面需要访问Model对象,该对象包含存储为数组,字符串等的数据。在运行时填充一个简单的模型,用户可以在整个应用程序生命周期中添加它。例如,下面列出的代码来自我的AppDelegate文件,它将指向裸机模型的指针传递给Project View Controller。这很好用:选项卡应用程序使用导航控制器阵列堆栈;因为我知道Project页面位于索引2处,所以我可以将模型发送给它。

我的问题与“项目”页面的子视图有关。例如,作为Project页面的子视图,有(或应该是)File_IO页面,用户在该页面处理文件操作。 File_IO页面还需要访问Model对象。但是当我尝试将Model指针从Project页面发送到File_IO页面时,我之前使用的技术(从AppDelegate到Project)不起作用。我指向FileIO ViewController中的空模型。

示例代码:这是在AppDelegate中,它工作正常:项目ViewController中的裸机模型填充了数据。

        //To the Project View Controller...
UINavigationController *project_NavigationController =
[[tabBarController viewControllers] objectAtIndex:2];
Project_ViewController *project_ViewController =
[[project_NavigationController viewControllers] objectAtIndex:0];
//This hides the navigation bar on the project page but it also removes the bar on any subsequent pages! They need to be programmmatically reset in ViewDidLoad.
[project_NavigationController setNavigationBarHidden:YES animated:YES];
project_ViewController.currentGeoModel = newGeoModel;

现在,我的Project_ViewController嵌入在NavigationController中,并有4个子ViweControllers。一个名为FileIO_ViewController。我想将currentModel从Project_ViewController传递给FileIO_ViewController。在 - (void)viewDidLoad方法下,我尝试了很多东西,但是没有用。例如,

UINavigationController *project_NavigationController = (UINavigationController *) self.presentedViewController;
FileIO_ViewController *fileIO_ViewController = [[project_NavigationController viewControllers] objectAtIndex:1];
fileIO_ViewController.currentModel = currentModel;

编译但是当我尝试访问FileIO_ViewController方法中的currentModel时,它是空的。

如果有人可以抽出时间来帮助我,我将非常感激。对我来说最好的答案是以一个显式代码示例的形式,显示如何将指针传递给像我的Model这样的对象,从ViewController到另一个ViewController,在那里你没有明确知道子VC在堆栈中的位置。 (在我的例子中我使用了索引1,但我实际上并不知道FileIO_ViewController在哪个索引处存在,因为我在Project_ViewController下有三个其他的ViewControllers。我已经尝试了几个整数但没有成功。)

如果你确实回答了这个问题,请考虑我是一个新手,当谈到iOS 6和目标C - 登山苹果已经很长时间了,而且我还没有接近顶端!

由于

蒂姆雷德菲尔德 挪威

1 个答案:

答案 0 :(得分:-1)

如果你的应用程序有一个共享的单一模型,你不应该主动传递指针,你应该从一个位置使模型可用,并将它留给单个对象,以便在需要时访问同一模型至。模型指针的良好位置在您的应用程序委托中。

在appDelegate的.h文件中,为您的模型声明一个属性:

  //appDelegate.h

  @property (nonatomic, strong) MyAppModel* appModel;

在appDelegate中实例化模型后,只需将其分配给属性:

   //appDelegate.m

  - (BOOL)application:(UIApplication *)application 
           didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.appModel  = [[MyAppModel alloc] init];
    //set up bare-bones appModel here
    return YES;

}

然后,您可以从任何需要模型数据的viewController访问此属性:

#import appDelegate.h;

AppDelegate* appDelegate = [UIApplication sharedApplication] delegate;
MyModel* model = appDelegate.model

(更好的是,让模型对象进入它自己的Singleton object,但是使用appDelegate会让你开始)

如果您需要来传递模型,那么您需要注意将它们传递给正确的对象。这是您现有代码破坏的地方。例如,您对NavigationController堆栈的结构做了很多假设。但是,无论何时通过从顶部弹出控制器将向下移动,都会完全失去顶级控制器实例。当你回归'通过在堆栈上向前移动到该控制器,实际上创建了一个新实例(除非你已经注意保持指针悬空并确保推送到该指针)。如果您在这方面需要更多帮助,则需要准确描述应用程序的布局,以及 如何创建viewControllers,navigationController堆栈等。

更新(发表评论后)

如果您对该模型的更改在整个应用中有效,那么我就不知道为什么您无需在何时需要访问该模型通过appDelegate.model进入应用程序。如果你有模型的并发版本,你可以考虑制作一个单例数据管理器对象,它可以处理存储模型数组(或模型历史)的细节,并提供正确的模型。请求。原理是相同的 - 而不是主动将模型对象传递给viewControllers,让他们在需要时从集中源请求数据。

关于你的描述"现在,我的Project_ViewController嵌入在NavigationController中,并有4个子ViewControllers。",我不认为你已经完全掌握了Classes,Storyboard场景和实例。

您在故事板的一部分中有这样的安排:

UINavigationController
       |                    push                     push                     push
       |->UIViewController1 -----> UIViewController2 -----> UIViewController3 ----->
                            segue                    segue                    segue

您谈到通过访问NavController的堆栈将数据直接从VC1(例如)传递到VC3。

您需要考虑的是故事板描述了一个模板,该模板显示了实例在实例化时的相互关系。它们实例化只是因为故事板已加载。当你到达VC1时,在你进入模板之前就已经设定了转向VC2和VC3的能力,但是在你启动segue之前,VC2和VC3都没有 - 作为实例。 segue进程实例化它的destinationViewController因此将数据从VC1直接传递到VC3是没有意义的。当您在VC1时,navController的堆栈只包含一个项目(VC1实例);当您转到VC2时,它会包含VC1和VC2的实例,只有当您真正转到VC3时,才会创建实例并将其放入堆栈中。

单步执行代码:

UINavigationController *project_NavigationController = 
                            (UINavigationController *) self.presentedViewController;

presentedViewController属性适用于modal segues,其中有一个展示,以及一个呈现的视图控制器。另一方面,NavControllers使用push segues(因为它们将子viewControllers推送到它们的viewControllers堆栈,您可以从中获取指向它们的指针)。

在此上下文中,self.presentedViewController为nil,您将其分配给新变量。代码什么都不做,但编译器不会抱怨。

FileIO_ViewController *fileIO_ViewController = 
                    [[project_NavigationController viewControllers] objectAtIndex:1];

project_NavigationControlle是零,所以它的属性都是零。 fileIO_ViewController没有问题。  同样在最后一行你发送一条消息给nil,这不是一个错误,但是有点多余。