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

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

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

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

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


当前回答

在我的例子中,我使用了一个单例类,它可以作为一个全局对象,允许访问应用程序中几乎所有地方的数据。

第一件事是构建一个单例类。请参考页面我的Objective-C单例应该是什么样子?。

为了使对象全局可访问,我只需将其导入appName_Prefix.pch中,该程序用于在每个类中应用import语句。

为了访问和使用这个对象,我简单地实现了一个类方法来返回共享实例,该实例包含自己的变量。

其他回答

这是一个非常棒的教程,适合任何想要的人。下面是示例代码:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"myIdentifer]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        myViewController *destViewController = segue.destinationViewController;
        destViewController.name = [object objectAtIndex:indexPath.row];
    }
}

OP没有提到视图控制器,但有很多答案都提到了,所以我想补充一下LLVM的一些新功能,以便在希望将数据从一个视图控制器传递到另一个视图,然后获取一些结果时更容易。

故事板片段、ARC和LLVM块使我比以往任何时候都容易。上面提到的一些答案已经提到了故事板和片段,但仍然依赖于授权。定义委托当然有效,但有些人可能会发现传递指针或代码块更容易。

使用UINavigator和segue,可以轻松地将信息传递给从属控制器并获取信息。ARC使传递从NSObjects派生的对象的指针变得简单,因此如果您希望从属控制器为您添加/更改/修改某些数据,请将指针传递给可变实例。块使传递动作变得容易,因此如果您希望从属控制器调用更高级别控制器上的动作,请传递一个块。您可以定义块以接受任何数量的对您有意义的参数。如果更适合的话,您还可以设计API以使用多个块。

下面是segue胶水的两个小例子。第一个简单明了地显示了传递给输入的一个参数,第二个用于输出。

// Prepare the destination view controller by passing it the input we want it to work on
// and the results we will look at when the user has navigated back to this controller's view.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    [[segue destinationViewController]

     // This parameter gives the next controller the data it works on.
     segueHandoffWithInput:self.dataForNextController

     // This parameter allows the next controller to pass back results
     // by virtue of both controllers having a pointer to the same object.
     andResults:self.resultsFromNextController];
}

第二个示例显示为第二个参数传递回调块。我喜欢使用块,因为它将相关细节紧密地保存在源代码中——更高级别的源代码中。

// Prepare the destination view controller by passing it the input we want it to work on
// and the callback when it has done its work.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    [[segue destinationViewController]

     // This parameter gives the next controller the data it works on.
     segueHandoffWithInput:self.dataForNextController

     // This parameter allows the next controller to pass back results.
     resultsBlock:^(id results) {
         // This callback could be as involved as you like.
         // It can use Grand Central Dispatch to have work done on another thread for example.
        [self setResultsFromNextController:results];
    }];
}

在使用.xib文件时,委派是执行此类操作的唯一解决方案。然而,之前的所有答案都是针对.xib文件的脚本。你需要使用授权。这是您可以使用的唯一解决方案。

另一个解决方案是使用单例类模式。初始化一次并在整个应用程序中使用它。

在为iOS创建应用程序时,您必须始终遵循MVC概念。

有两种情况下,您可能希望将数据从ViewController传递到另一个:

当层次结构中有一个“A”ViewContoller,并且您希望将一些数据发送到“B”,这是下一个视图控制器。在这种情况下,您必须使用Segue。只需为segue设置一个标识符,然后在“A”VC中编写以下代码:override func prepare(segue:UIStoryboardSegue,sender:Any?){如果segue.identifier==“A到B segue-identifier”{让bViewController=segue.destination为!UIDocumentBrowserViewControllerbViewController.data=某些数据}}当有一个A将B作为模态(或嵌入)打开时。现在,B视图控制器应该对其父对象视而不见。因此,将数据发送回A的最佳方法是使用委派。在B视图控制器和委托属性中创建委托协议。因此,B将向其代表报告(发送数据)。在A视图控制器中,我们实现了B视图控制器的委托协议,并将在prepare(forSegue:)方法中将self设置为B视图控制器中的委托属性。

这就是它应该正确实现的方式。

嗯,我们有几种方法可以使用委派系统或使用故事板Segue:

使用setter和getter方法,如viewController.h@属性(保留,非原子)NSString*str;现在,在viewController.m中@合成str;这里我有一个PDF URL和一个segue到另一个viewController,像这样,pdfObject是我的pdfModel。它基本上是一个NSOBJECT类。str=[NSString stringWithFormat:@“%@”,pdfObject.objPath];NSLog(@“pdfUrl:***:%@:***:”,pdfUrl);[self-performSegueWithIdentifier:@“programPDFViewController_segue”sender:self];#pragma标记-导航//在基于情节提要的应用程序中,您通常需要在导航之前做一些准备-(void)准备segue:(UIStoryboardSegue*)segue发件人:(id)发件人{if([[segue identifier]isEqualToString:@“programPDFViewController_segue”]){programPDFViewController*pdfVC=[segue destinationViewController];[pdfVC setRecivedPdfUrl:str];}}现在,我成功地接收了我的PDF URL字符串和其他ViewController,并在webview中使用该字符串。。。在处理这样的委托时,我有一个NSObject实用程序类,其中包含我的dateFormatter、sharedInstance、EscapeWhiteSpaceCharacters、convertImageToGrayScale等方法,以及我在整个应用程序中使用过的其他方法,现在在文件实用程序中使用。在这种情况下,您不需要在每次将数据从一个视图控制器解析到另一个视图时都创建变量。有一次,您在fileutility.h中创建了一个字符串变量。只需将其设为零并再次使用。@接口实用程序:NSObject文件实用程序.h:+(实用程序*)共享实例;@属性(非原子,保留)NSString*strUrl;现在在文件实用程序.m中:@实施实用程序+(实用程序*)共享实例{静态实用程序*sharedObj=nil;如果(sharedObj==nil){sharedObj=[[utilities alloc]init];}返回sharedObj;}现在完成了,请访问文件firstViewController.m并调用委托NSString*str=[NSString stringWithFormat:@“%@”,pdfObject.objPath];[连接共享实例].strUrl=nil;[连接共享实例].strUrl=str;现在直接转到文件secondViewController.m,在不创建变量的情况下使用它我所做的一切:-(无效)视图将出现:(BOOL)动画{[超级视图将出现:是];[self-webViewMethod:[Connection sharedInstance].strUrl];}-(void)WebViewMethod:(NSString)Url{//使用webview。享受编码:D}

这种委托工作在内存管理方面是可靠的。