0

我正在尝试使用委托将值从一个 VC 传递到另一个。我想我误解了它应该工作的方式。

在我的主要 ViewController.h 我有这个:

@protocol defaultLocationChoice <NSObject>

- (NSString *) locChoice;

@end

在我的 PreferencesViewController.h 和 ChooseServerViewController.h 中,我已经defaultLocationChoice在 @interface 部分声明了属性,如下所示:

@property (nonatomic, assign) id <defaultLocationChoice> locationDelegate;

两者也是合成的。

当用户从 PreferencesViewController 转到 ChooseServerViewController 时,准备 segue 的代码是:

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

    if ([segue.identifier isEqualToString:@"toServerChoice"]) {
        ChooseServerViewController *viewController = (ChooseServerViewController *)segue.destinationViewController;
        viewController.locationDelegate = self;

    }

}

在 ChooseServerViewController 中选择单元格时,我调用:

[self locChoice];

这是:

- (NSString *) locChoice {
    NSLog(@"Cell Vale Loc choice %@",cellValue);
    return cellValue;
}

NSLog 验证返回的值是否正确。

现在,我想我明白了,委托中 LocChoice 的值现在是返回的值,不是吗?

当用户返回(NavController)时,PreferencesViewController 具有:

-(void) viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];
    defaultLocation = [locationDelegate locChoice];
    [self.tableView reloadData];  
}

我期待 defaultLocation 的值现在等于传递给 locChoice 的值。但是,当表格重新加载时,有问题的单元格仍然是空白的,这意味着我期望发生的事情没有发生。

有任何想法吗?

4

2 回答 2

2

如果我正确地遵循了你的代码,你不需要在你的ChooseServerViewController, only中采用提到的协议PreferencesViewController

原因是您希望将数据发送之前的视图控制器。尝试:

@protocol defaultLocationChoice <NSObject>
    - (void) locChoice:(NSString*)choice;
@end

让您PreferencesViewController实现该方法,以便它接收选择。您必须将其存储在适当的实例变量中。

// in PreferencesViewController.m
-(void)locChoice:(NSString*)choice {
    self.choice = choice;  // this just my example
}

当做出选择(在 中ChooseServerViewController)发送回选择时,调用:

// this is in 'ChooseServerViewController.m' some where appropriate
[self.delegate locChoice:cellValue];

您的实现只是对单元格值不做任何事情(甚至不存储它,只是记录它)。当您返回 时PreferencesViewController,您现在将拥有选定的值,并且该视图控制器可以随心所欲地使用它。

协议在某种程度上类似于 Java 或 C# 中的接口,但更灵活。

更新

的声明ChooseServerViewController应如下所示:

#import "FileWithProtocolDecalration.h"
@interface ChooseServerViewController
.
.
.
@property ( nonatomic,assign) id<defaultLocationChoice> delegate;
.
.
.
@end
于 2013-03-09T03:41:17.807 回答
0

我想你确实有一些误解

协议和委托是传递的东西。换句话说,有人需要成为接收者,有人需要成为发送者。在你的情况下。
将您的协议更新为此

@protocol defaultLocationChoice <NSObject>

- (void)locChoice:(NSString *)updateString;  // the method from delegate and implementer must be exact

@end  

并将协议实现为 ViewController 作为接收器

@interface VCReceiver : UIViewController <defaultLocationChoice>

然后稍后在 VCReceiver

- (void)viewDidLoad {  
    ChooseServerViewController *vcSender = [[ChooseServerViewController alloc] init];
    [vcSender setLocationDelegate:self]; // this is like saying. i have implemented method from protocol in this file (self)
}
- (void)locChoice:(NSString *)updateString {
    // update the VCReceiver here
    // or access vcSender value 
    // or use the updateString value
}

然后在ChooseServerViewController locChoice:方法(您的示例中的那个)替换为这个并调用[self updateChoice]

- (void)updateChoice {
    if ([self.locationDelegate respondsToSelector:@selector(locChoice:)]) {
         [self.locationDelegate locChoice:aStringToUpdate]; // this will call VCReceiver locChoice
   }

它不必返回任何内容,因为它实际上是在调用 VCReceiver 方法来告诉它已ChooseServerViewController准备好读取值。

于 2013-03-09T03:35:38.317 回答