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

时间:2022-04-16 16:10:17

This question already has an answer here:

这个问题在这里已有答案:

I know this question has been asked and answered many times over here. But I am dealing with this thing for the first time and still not able to get the perfect implementation of it in my mind. Here's the code I have the delegate method I implement to pass data from SecondViewController to FirstViewController.

我知道这个问题在这里被多次询问和回答。但是我第一次处理这个问题,但仍然无法在脑海中完美地实现它。这是我实现的代码方法的代码,用于将数据从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

Am I doing it correctly? All I want it to send the data in self.dataInSecondViewController to FirstViewController and store it over there in the NSArray property sampleData of FirstViewController.

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

Somehow I am not able to access sendDataBackToFirstController in FirstViewController. What other things I am missing implementing to access sendDataBackToFirstController there?

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

3 个解决方案

#1


9  

Not quite right. First you need to assign the delegate property in the first view controller so the second view controller knows which object to send messages to.

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

FirstViewController.m

controller.delegate = self;

Second, you have the sending and receiving of your delegate method backwards. You have it setup in a way where the FirstViewController is expected to call sendDataBackToFirstController on the second controller. In a delegate pattern, the SecondViewController is the one that sends the message and optionally sends data with that method. So, you should change your delegate declaration to something like this:

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

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

Then, when your SecondViewController finishes its tasks and needs to notify its delegate, it should do something like this:

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

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

I added an extra if statement here to check to make sure the delegate will respond to the method we want to send it before actually sending it. If we had optional methods in our protocol and did not have this, the app would crash.

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

Hope this helps!

希望这可以帮助!

#2


4  

Please follow this

请关注此

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

#3


1  

First change @property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject; to @property (nonatomic, weak) id <sampleDelegate> sampleDelegateObject; to prevent retain cycle search google with that word for explanation.

首先更改@property(非原子,强)id sampleDelegateObject; to @property(nonatomic,weak)id sampleDelegateObject;防止保留周期搜索谷歌用这个词来解释。

Second your protocol should be

你的协议应该是第二个

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

and when you want to send data back you call [self.sampleDelegateObject sendDataBackToFirstControoler:yourData]; first view controller must implement those method in protocol.

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

#1


9  

Not quite right. First you need to assign the delegate property in the first view controller so the second view controller knows which object to send messages to.

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

FirstViewController.m

controller.delegate = self;

Second, you have the sending and receiving of your delegate method backwards. You have it setup in a way where the FirstViewController is expected to call sendDataBackToFirstController on the second controller. In a delegate pattern, the SecondViewController is the one that sends the message and optionally sends data with that method. So, you should change your delegate declaration to something like this:

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

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

Then, when your SecondViewController finishes its tasks and needs to notify its delegate, it should do something like this:

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

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

I added an extra if statement here to check to make sure the delegate will respond to the method we want to send it before actually sending it. If we had optional methods in our protocol and did not have this, the app would crash.

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

Hope this helps!

希望这可以帮助!

#2


4  

Please follow this

请关注此

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

#3


1  

First change @property (nonatomic, strong) id <sampleDelegate> sampleDelegateObject; to @property (nonatomic, weak) id <sampleDelegate> sampleDelegateObject; to prevent retain cycle search google with that word for explanation.

首先更改@property(非原子,强)id sampleDelegateObject; to @property(nonatomic,weak)id sampleDelegateObject;防止保留周期搜索谷歌用这个词来解释。

Second your protocol should be

你的协议应该是第二个

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

and when you want to send data back you call [self.sampleDelegateObject sendDataBackToFirstControoler:yourData]; first view controller must implement those method in protocol.

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