如何使用委托和协议返回对象

时间:2013-12-10 03:22:34

标签: objective-c ios7

我正在开发这个项目,我有一个User类,我的主视图控制器和我的SetUp控件查看器(第二个控件查看器)。 User类具有所有User属性,主视图控制器创建用户名/密码,然后调用SetUp视图控制器,SetUp视图控制器允许用户输入其他信息。我在我的SetUp视图控制器中创建了一个协议,在用户在第二个视图控制器中输入附加信息后,在我的主视图控制器中调用委托方法。委托方法返回一个User对象,但这是我迷路的地方。返回的User对象在哪里?它肯定不会去我想要的地方。

/**Main View Controller Implementation**/
#import "BWViewController.h"
#import "User.h"

@interface BWViewController ()

@end

@implementation BWViewController

@synthesize holdPassword,holdUserName,holdZone,holdArea;

-(IBAction)signUpButton
{

    firstUser = [[User alloc] init];
    firstUser.userName = userNameField.text;
    firstUser.password = passwordField.text;

    SetUp *setUpView = [[SetUp alloc] initWithNibName:Nil bundle:Nil];
    setUpView.delegate = self;

    User * bufferUser;

    bufferUser = [self presentViewController:setUpView animated:YES completion:^{ }];   /**This is where I want the User object from the delegate method return to**/


}

/**Delegate method in Main view controller**/

-(User*) sendUserInfoBack: (SetUp *) SetUpController didFinishWithZoneInfo:(NSString*)zoneInfo didFinishWithAreaInfo:(NSString*) areaInfo
{

    User*holdUser;
    holdZone = zoneInfo;
    holdArea = areaInfo;

    holdUser.userZone = holdZone;
    holdUser.userArea = holdArea;

    return holdUser;  /**return this to bufferUser object in method above**/
}

/**Second View controller Interface**/
#Import "User.h"
@class SetUp;

@protocol SetUpControllerDelegate <NSObject>

-(User*) sendUserInfoBack: (SetUp *) SetUpController didFinishWithZoneInfo:(NSString*)zoneInfo didFinishWithAreaInfo:(NSString*) areaInfo;

@property (weak,nonatomic) id<SetUpControllerDelegate>delegate;

@end


/**Second View controller implementation**/
-(IBAction)goToMainView:(id)sender
{
    NSString * neededZoneStore = Zone.text;
    NSString * areaStore = Area.text;

    User * user = [[User alloc] init];

    user.userZone = neededZoneStore;
    user.userArea = neededAreaStore;

    [self.delegate sendUserInfoBack:self didFinishWithZoneInfo:neededZoneStore didFinishWithAreaInfo:neededAreaStore];

    [self dismissViewControllerAnimated:YES completion:NULL];
}

1 个答案:

答案 0 :(得分:2)

[self.delegate sendUserInfoBack:self didFinishWithZoneInfo:neededZoneStore 
    didFinishWithAreaInfo:neededAreaStore];

因此,您可能永远不需要将self发送回代表。由于委托实例化了一个对象,委托已经知道self

您需要将协议更改为:

-(void)sendUserInfoBack:(User*)user;

然后,当您准备好发回此信息时,您只需将其称为:

[self.delegate sendUserInfoBack:user];

现在在委托类中,您需要从协议中实现该方法:

-(void)sendUserInfoBack:(User*)user {
    //do stuff with user
}

例如,您有holdZoneholdArea属性,因此您可以将方法编写为如下所示:

-(void)sendUserInfoBack:(User*)user {
    self.holdZone = user.userZone;
    self.holdArea = user.userArea;
    //then perhaps perform a segue, or whatever.
}

当我花一些时间查看你的问题时,我认为问题变得更加清晰了。

这一行:

bufferUser = [self presentViewController:setUpView animated:YES completion:^{ }];

错了。您可以在委托方法sendUserInfoBack中从其他类中获取您的信息。除了来自其他类之外,你不应该调用这个方法。

您的-(IBAction)signUpButton方法应启动视图,然后应该是方法的结尾。现在这个视图控制器只是处于待机状态,而另一个视图(第一个视图控制器委托)则等待它的响应。

当新启动的视图完成后,它会自行关闭,并在原始视图上调用sendUserInfoBack。这就是你知道模态视图被清除并且原始视图可以继续执行功能的方式。

因此,在完成另一个视图后你想要做的任何事情都应该放在sendUserInfoBack方法中。


重要的是要记住,虽然委托实现了委托方法,但委托不是调用方法的委托,也不能对返回值做任何事情。委托方法的返回值将由调用该方法的对象使用。

例如,考虑何时实施UITableViewcellForRowAtIndexPath的返回类型为:UITableViewCell。但是你在哪里获得这个回报值?你没有。您可以覆盖此委托方法,以便可以自定义单元格的设置方式。视图控制器为委托的UITableView类会覆盖此方法...但是UITableView在其委托上调用该方法,然后使用返回值(它刚设置的单元格)来执行此操作自己做更多的工作。

如果您需要在返回该值后在sendUserInfoBack类中完成更多工作,则只希望SetUpControllerDelegate具有返回值。

例如,如果我们这样做:

- (BOOL)sendUserInfoBack:(User*)user;

现在覆盖此方法的委托可以放入一些逻辑来返回YESNO,具体取决于... {然后我们会在SetUpControllerDelegate中使用它:

if([self.delegate sendUserInfoBack:user]) {
    // everything's fine, we can dismiss view
    [self dismissViewControllerAnimated:YES completion:nil];
} else {
    // everything wasn't fine, we need to try again
    // pop up a UIAlertView perhaps try to get better info
}

这只是一个例子。