我对iOS和Objective-C以及整个MVC范式都是新手,我一直坚持以下几点:

我有一个充当数据输入表单的视图,我想让用户选择多个产品。产品列在另一个具有UITableViewController的视图中,我已启用多个选项。

如何将数据从一个视图传输到另一个视图?我会将UITableView上的选择保存在一个数组中,但如何将其传递回上一个数据输入表单视图,以便在提交表单时将其与其他数据一起保存到核心数据?

我在网上冲浪,看到一些人在应用程序委托中声明了一个数组。我读了一些关于单态的东西,但我不明白这些是什么,我读了关于创建数据模型的东西。

正确的执行方式是什么?我将如何执行?


当前回答

我在这个解决方案中搜索了很长时间,终于找到了它

@interface SecondViewController: UIviewController
{
    NSMutableArray *myAray;
    CustomObject *object;
}

现在在实现文件中,为这些对象分配内存,如下所示:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
     if (self)
     {
         // Custom initialization
         myAray=[[NSMutableArray alloc] init];
         object=[[CustomObject alloc] init];
     }
     return self;
}

现在您已经为数组和对象分配了内存。现在,您可以在推送此ViewController之前填充该内存。

转到SecondViewController.h并编写两个方法:

-(void)setMyArray:(NSArray *)_myArray;
-(void)setMyObject:(CustomObject *)_myObject;

在实现文件中,您可以实现以下功能:

-(void)setMyArray:(NSArray *)_myArray
{
     [myArra addObjectsFromArray:_myArray];
}

-(void)setMyObject:(CustomObject *)_myObject
{
     [object setCustomObject:_myObject];
}

期望CustomObject必须具有setter函数。

现在你的基本工作完成了。转到要推动SecondViewController的位置,执行以下操作:

SecondViewController *secondView= [[SecondViewController alloc] initWithNibName:@"SecondViewController " bundle:[NSBundle MainBundle]] ;
[secondView setMyArray:ArrayToPass];
[secondView setMyObject:objectToPass];
[self.navigationController pushViewController:secondView animated:YES ];

注意拼写错误。

其他回答

我喜欢基于NSProxy的模型对象和模拟对象的想法,以便在用户选择的内容可以取消时提交或丢弃数据。

传递数据很容易,因为它是一个对象或两个对象,如果你有一个UINavigationController控制器,你可以将对模型的引用保存在内部,所有推送视图控制器都可以直接从导航控制器访问它。

MVC中的M代表“模型”,而在MVC范式中,模型类的作用是管理程序的数据。模型与视图相反——视图知道如何显示数据,但它不知道如何处理数据,而模型知道如何使用数据,但不知道如何显示。模型可能很复杂,但不一定如此——应用程序的模型可能与字符串或字典数组一样简单。

控制器的作用是在视图和模型之间进行调解。因此,它们需要对一个或多个视图对象和一个或更多模型对象的引用。假设您的模型是一个字典数组,每个字典代表表中的一行。应用程序的根视图显示该表,它可能负责从文件加载数组。当用户决定向表中添加新行时,他们点击某个按钮,控制器将创建一个新的(可变的)字典并将其添加到数组中。为了填充该行,控制器创建一个详细视图控制器并为其提供新字典。详细视图控制器填充字典并返回。字典已经是模型的一部分,因此不需要发生其他任何事情。

您可以将数据保存在App代理中,以便通过应用程序中的视图控制器访问数据。您只需创建应用程序委托的共享实例:

AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

例如

如果声明NSArray对象*arrayXYZ,则可以通过appDelegate.arrayXYZ在任何视图控制器中访问它。

有很多方法可以做到这一点,选择正确的方法很重要。可能最大的架构决策之一在于如何在整个应用程序中共享或访问模型代码。

不久前,我写了一篇关于这一点的博客文章:共享模型代码。下面是一个简短的总结:

共享数据

一种方法是在视图控制器之间共享指向模型对象的指针。

在视图控制器(在导航或选项卡栏控制器中)上强制迭代以设置数据在prepareForSegue(如果是故事板)或init(如果是编程的)中设置数据

因为准备segue是最常见的,这里有一个例子:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    var next = segue.destinationViewController as NextViewController
    next.dataSource = dataSource
}

独立访问

另一种方法是一次处理满屏数据,而不是将视图控制器彼此耦合,将每个视图控制器耦合到它们可以独立访问的单个数据源。

我看到的最常见的方法是单例实例。因此,如果单例对象是DataAccess,则可以在UIViewController的viewDidLoad方法中执行以下操作:

func viewDidLoad() {
    super.viewDidLoad()
    var data = dataAccess.requestData()
}

还有其他工具也有助于传递数据:

关键价值观察NS通知核心数据NSFetchedResults控制器数据源

核心数据

核心数据的优点在于它具有相反的关系。因此,如果你只想给NotesViewController一个notes对象,你可以这样做,因为它与笔记本等其他东西有相反的关系。如果需要NotesViewController中笔记本上的数据,可以通过执行以下操作返回对象图:

let notebookName = note.notebook.name

在我的博客文章:共享模型代码中了解更多信息

使用通知中心将数据从一个视图传递到另一个视图。

观察者-收听者模式效果最好。另一种解决方法是在两个类中创建相同的对象。

在类1中创建类2对象。访问要传递的数据对象,设置它们,然后按下视图控制器。