使用委托和协议在2个UIViewController之间传递数据

时间:2013-12-17 03:57:32

标签: ios uiviewcontroller delegates protocols

我知道这个问题在这里已被多次询问和回答。但我第一次处理这个问题,仍然无法在脑海中完美地实现它。以下是我使用委托方法将代码从SecondViewController传递到FirstViewController的代码。

FirstViewController.h

#import "SecondViewController.h"

@interface FirstViewController : UITableViewController<sampleDelegate> 
@end

FirstViewController.m

@interface FirstViewController ()

// Array in which I want to store the data I get back from SecondViewController.
@property (nonatomic, copy) NSArray *sampleData;
@end

@implementation FirstViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
   SecondViewController *controller = [[SecondViewController alloc] init];          
   [self.navigationController pushViewController:controller animated:YES];
}
@end

SecondViewController.h

@protocol sampleDelegate <NSObject>
- (NSArray*)sendDataBackToFirstController;
@end

@interface SecondViewController : UITableViewController
@property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject;
@end

SecondViewController.m

@interface SecondViewController ()
@property (strong, nonatomic) NSArray *dataInSecondViewController;
@end

@implementation SecondViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.dataInSecondViewController = [NSArray arrayWithObjects:@"Object1", @"Object2", nil];
}

- (NSArray*)sendDataBackToFirstController
{
    return self.dataInSecondViewController;
}
@end

我做得对吗?我希望它将self.dataInSecondViewController中的数据发送到FirstViewController并将其存储在NSArray的{​​{1}}属性sampleData中。

不知何故,我无法访问FirstViewController中的sendDataBackToFirstController。我在实现访问FirstViewController时还缺少哪些其他内容?

3 个答案:

答案 0 :(得分:11)

不太对劲。首先,您需要在第一个视图控制器中分配委托属性,以便第二个视图控制器知道要将消息发送到哪个对象。

FirstViewController.m

controller.delegate = self;

其次,您向后发送和接收您的委托方法。您可以通过FirstViewController在第二个控制器上调用sendDataBackToFirstController的方式进行设置。在委托模式中,SecondViewController是发送消息并可选择使用该方法发送数据的模式。因此,您应该将委托声明更改为以下内容:

@protocol sampleDelegate <NSObject>
- (void)secondControllerFinishedWithItems:(NSArray* )newData;
@end

然后,当您的SecondViewController完成其任务并需要通知其委托时,它应该执行以下操作:

// ... do a bunch of tasks ...
// notify delegate
if ([self.delegate respondsToSelector:@selector(secondControllerFinishedWithItems:)]) {
    [self.delegate secondControllerFinishedWithItems:arrayOfNewData];
}

我在这里添加了一个额外的if语句来检查以确保委托将在实际发送之前响应我们想要发送它的方法。如果我们的协议中有可选方法但没有这个,那么应用程序就会崩溃。

希望这有帮助!

答案 1 :(得分:4)

请按照

进行操作

FirstViewController.h

   #import "SecondViewController.h"

   @interface FirstViewController : UITableViewController<sampleDelegate> 
   @end

FirstViewController.m

  @interface FirstViewController ()

  // Array in which I want to store the data I get back from SecondViewController.
  @property (nonatomic, copy) NSArray *sampleData;
  @end

 @implementation FirstViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 {
   SecondViewController *controller = [[SecondViewController alloc] init]; 
   controller.sampleDelegateObject=self;      
  [self.navigationController pushViewController:controller animated:YES];

 }

  //implementation of delegate method
  - (NSArray*)sendDataBackToFirstController
{
  return self.dataInSecondViewController;
}
 @end

SecondViewController.h

 @protocol sampleDelegate <NSObject>
- (NSArray*)sendDataBackToFirstController;
@end

@interface SecondViewController : UITableViewController
@property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject;
@end
SecondViewController.m

 @interface SecondViewController ()
 @property (strong, nonatomic) NSArray *dataInSecondViewController;
 @end

 @implementation SecondViewController

 - (void)viewDidLoad
{
  [super viewDidLoad];
  self.dataInSecondViewController = [NSArray arrayWithObjects:@"Object1", @"Object2", nil];
   //calling the delegate method
  [sampleDelegateObject sendDataBackToFirstController];
}


  @end

答案 2 :(得分:1)

首先改变 @property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject;@property (nonatomic, weak) id <sampleDelegate> sampleDelegateObject;以防止使用该字词保留周期搜索谷歌进行解释。

二 你的协议应该是

@protocol sampleDelegate <NSObject>
- (void)sendDataBackToFirstController:(NSArray*)dataToSendBack;
@end

当您想要发回数据时,请调用[self.sampleDelegateObject sendDataBackToFirstControoler:yourData];第一个视图控制器必须在协议中实现这些方法。