调用具有多个子视图层次结构的协议方法

时间:2012-03-11 22:07:37

标签: iphone objective-c ios4

我是Obj-C的新手并且学习使用协议和委托。

当只有两个视图时,我可以毫不费力地执行协议/传递数据的示例,但是,当我尝试在有多个子视图时调用方法时,我收到“无法识别的选择器”错误。

例如,在我有

的情况下
  • FirstViewController
  • SecondViewController
  • ThirdViewController

我希望ThirdViewController回调给FirstViewController。

通用代码类似于:

在FirstViewController.h中

@interface FirstViewController : UIViewController <MyProtocol>
在firstViewController.m中

//present a second controller which will control settings for the app
SecondViewController *secondViewController = [[SecondViewController alloc]     initWithNibName:@"secondViewController" bundle:nil];

secondViewController.delegate= self;

secondViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;

[self presentModalViewController: secondViewController animated: YES];

以后

-(void) aMethod{
    //carry out some action here
}
在secondViewController.m中

//present a third controller...maybe a table view for selecting music   
ThirdViewController *thirdViewController = [[ThirdViewController alloc] initWithNibName:@"thirdViewController" bundle:nil];

thirdViewController.delegate= self;

thirdViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;

[self presentModalViewController: thirdViewController animated: YES];
在ThirdViewContoller.h中

//Create a protocol to implement options back on the firstViewController
@protocol MyProtocol;

@interface thirdViewController
{
    IBOutlet UIButton *aButton;
}

@property (nonatomic, weak) id<MyProtocol> delegate;
-(IBAction) callMethod:(id)sender;
@end

@protocol MyProtocol <NSObject>
- (void) aMethod;
@end
在ThirdViewController.m中

@synthesize delegate;

-(IBAction) callMethod:(id)sender{
    [self.delegate aMethod];
}

运行时,似乎消息只发送回secondViewController而不是firstViewController,因为错误是:

- [SecondViewController aMethod:]:无法识别的选择器发送到实例0x19d620

我认为设置尚未学习的代理出口有一些基本概念,或者程序的结构是错误的。

有许多代码只使用两个在这里运行良好的视图,但我没有找到多个视图的大量信息。如果我的程序设计真的不对,我会提前道歉。

1 个答案:

答案 0 :(得分:1)

您需要SecondViewController符合您的协议:

@interface SecondViewController : UIViewController <MyProtocol>

您尝试在第二个视图控制器上调用仅存在于第一个视图控制器中的方法。如果要与第一个视图控制器进行通信,则必须定义第二个协议来执行此操作。

要了解协议的功能和限制,这是一个非常好的学术练习,但您也应该注意命名中的冲突。在命名协议时尽量使其具有描述性。理想情况下,您有一组看起来像这样的头文件:

@interface FirstViewController : UIViewController <SecondViewControllerDelegate>
@end

第二个视图控制器:

@protocol SecondViewControllerDelegate <NSObject> 
-(void)someSecondViewControllerDelegateMethod;
@end

@interface SecondViewController : UIViewController <ThirdViewControllerDelegate>

@protocol (nonatomic, weak) id <SecondViewControllerDelegate> delegate;

@end

最后,第三个视图控制器:

@protocol ThirdViewControllerDelegate <NSObject> 
-(void)someThirdViewControllerDelegateMethod;
@end

@interface ThirdViewController : UIViewController

@protocol (nonatomic, weak) id <ThirdViewControllerDelegate> delegate;

@end

所以第二个视图控制器可以实现-(void)someThirdViewControllerDelegateMethod,它看起来像:

-(void)someThirdViewControllerDelegateMethod
{
    [self.delegate someFirstViewControllerDelegateMethod];
}

这就是第三个视图控制器如何回调第一个视图;它有点级联并传递信息。