Objective c 调用ViewController';从它的观点来看';s子视图?
我在跟我的前同事一起做一个项目。代码很棒,除了一个 主控制器Objective c 调用ViewController';从它的观点来看';s子视图?,objective-c,ios,ios4,Objective C,Ios,Ios4,我在跟我的前同事一起做一个项目。代码很棒,除了一个 主控制器 @interface MainController : UIViewController { } @property (nonatomic, strong) IBOutlet HeaderBar *headerBar; - (void)setup; - (IBAction)refreshHeader; @end @implementation MainController - (void)setup{ Head
@interface MainController : UIViewController {
}
@property (nonatomic, strong) IBOutlet HeaderBar *headerBar;
- (void)setup;
- (IBAction)refreshHeader;
@end
@implementation MainController
- (void)setup{
HeaderBar *hb = [[HeaderBar alloc] initWithNibNames:@"HeaderBar"];
self.headerBar = hb;
}
- (IBAction)refreshHeader {
//Do something with headerBar's properties
//For example, [self.headerBar someiVar];
}
- (void)anotherSetup{
FooterBar *fb = [[FooterBar alloc] initWithNibNames:@"FooterBar"];
fb.mainController = self;
self.footerBar = fb;
}
#import "MainController.h"
@interface FooterBar : UIViewController {
}
@property (nonatomic, strong) MainController *mainController;
- (void)someMethod;
@end
@implementation FooterBar
@synthesize mainController;
- (void)someMethod {
[self.mainController someMainControllerMethod];
}
然后,有一个按钮作为HeaderBar视图的子视图。此按钮与第一响应者的方法绑定,该方法显示为刷新标题
@interface MainController : UIViewController {
}
@property (nonatomic, strong) IBOutlet HeaderBar *headerBar;
- (void)setup;
- (IBAction)refreshHeader;
@end
@implementation MainController
- (void)setup{
HeaderBar *hb = [[HeaderBar alloc] initWithNibNames:@"HeaderBar"];
self.headerBar = hb;
}
- (IBAction)refreshHeader {
//Do something with headerBar's properties
//For example, [self.headerBar someiVar];
}
- (void)anotherSetup{
FooterBar *fb = [[FooterBar alloc] initWithNibNames:@"FooterBar"];
fb.mainController = self;
self.footerBar = fb;
}
#import "MainController.h"
@interface FooterBar : UIViewController {
}
@property (nonatomic, strong) MainController *mainController;
- (void)someMethod;
@end
@implementation FooterBar
@synthesize mainController;
- (void)someMethod {
[self.mainController someMainControllerMethod];
}
代码按他的要求运行良好。但是,即使我是iOS开发新手,我也不太了解FirstResponder。我觉得这种设计方法不对
因为那个按钮属于headerBar的视图。这应该和headerBar的方法有关,对吧?
(假设headerBar也是控制器)
然后,找到一种方法将数据/结果/消息从headerBar发送到MainController,而不是使用firstResponder直接发送到MainController
如果是这样的话,我怎样才能将数据/结果/消息从HeaderBar的方法发送到MainController的方法之一,而不是使用代码其他部分中出现的方法。(我对此也感觉不好,它看起来很奇怪。它看起来像,在两个控制器之间以错误的方式创建关系。)
主控制器
@interface MainController : UIViewController {
}
@property (nonatomic, strong) IBOutlet HeaderBar *headerBar;
- (void)setup;
- (IBAction)refreshHeader;
@end
@implementation MainController
- (void)setup{
HeaderBar *hb = [[HeaderBar alloc] initWithNibNames:@"HeaderBar"];
self.headerBar = hb;
}
- (IBAction)refreshHeader {
//Do something with headerBar's properties
//For example, [self.headerBar someiVar];
}
- (void)anotherSetup{
FooterBar *fb = [[FooterBar alloc] initWithNibNames:@"FooterBar"];
fb.mainController = self;
self.footerBar = fb;
}
#import "MainController.h"
@interface FooterBar : UIViewController {
}
@property (nonatomic, strong) MainController *mainController;
- (void)someMethod;
@end
@implementation FooterBar
@synthesize mainController;
- (void)someMethod {
[self.mainController someMainControllerMethod];
}
页脚栏
@interface MainController : UIViewController {
}
@property (nonatomic, strong) IBOutlet HeaderBar *headerBar;
- (void)setup;
- (IBAction)refreshHeader;
@end
@implementation MainController
- (void)setup{
HeaderBar *hb = [[HeaderBar alloc] initWithNibNames:@"HeaderBar"];
self.headerBar = hb;
}
- (IBAction)refreshHeader {
//Do something with headerBar's properties
//For example, [self.headerBar someiVar];
}
- (void)anotherSetup{
FooterBar *fb = [[FooterBar alloc] initWithNibNames:@"FooterBar"];
fb.mainController = self;
self.footerBar = fb;
}
#import "MainController.h"
@interface FooterBar : UIViewController {
}
@property (nonatomic, strong) MainController *mainController;
- (void)someMethod;
@end
@implementation FooterBar
@synthesize mainController;
- (void)someMethod {
[self.mainController someMainControllerMethod];
}
我读了一些其他相关的问题,大多数人说另一种方法是定义协议和委派,这是最好的方法吗?这是唯一的办法吗?而不是两个控制器相互通信
欢迎任何建议,纠正我的误解也欢迎。我将不得不在这个项目上工作几个月,它只是在第二阶段从五。所以,我希望有尽可能少的错误设计
致意
另外,如果代码不正确,我很抱歉,它不是实际的代码。有些地方可能不正确,但是,希望你们能看到图片。是的,这是最好的方法。这叫做委托设计模式。这实际上是两个控制器相互通信 我在这里看到的唯一问题是在FooterBar中保留MainController。您不应该这样做,因为这会导致retain循环,阻止对象被释放。(对象A保留B,对象B保留A,因此它们的保留计数永远不会为0) 因此,与其(在页脚栏处)拥有: 你应该:
@property (nonatomic, assign) MainController *mainController;
或者,为了更加通用(如果需要),您可以创建一个协议来描述委托所需的方法。然后让MainController实现该协议
//FooterBar.h
@protocol FooterBarDelegate <NSObject>
-(void)aNeededMethod;
@end
@interface FooterBar : UIViewController {
}
@property (nonatomic, assign) id<FooterBarDelegate> mainController;
- (void)someMethod;
@end
//FooterBar.h
@电子门协议
-(无效)一种必要的方法;
@结束
@界面页脚栏:UIViewController{
}
@属性(非原子,赋值)id mainController;
-(无效)某种方法;
@结束
然后
//MainController.h
#import "FooterBar.h"
@interface MainController : UIViewController <FooterBarDelegate> {
}
//MainController.h
#导入“FooterBar.h”
@接口主控制器:UIViewController{
}
是的,这是最好的方法。这叫做委托设计模式。这实际上是两个控制器相互通信
我在这里看到的唯一问题是在FooterBar中保留MainController。您不应该这样做,因为这会导致retain循环,阻止对象被释放。(对象A保留B,对象B保留A,因此它们的保留计数永远不会为0)
因此,与其(在页脚栏处)拥有:
你应该:
@property (nonatomic, assign) MainController *mainController;
或者,为了更加通用(如果需要),您可以创建一个协议来描述委托所需的方法。然后让MainController实现该协议
//FooterBar.h
@protocol FooterBarDelegate <NSObject>
-(void)aNeededMethod;
@end
@interface FooterBar : UIViewController {
}
@property (nonatomic, assign) id<FooterBarDelegate> mainController;
- (void)someMethod;
@end
//FooterBar.h
@电子门协议
-(无效)一种必要的方法;
@结束
@界面页脚栏:UIViewController{
}
@属性(非原子,赋值)id mainController;
-(无效)某种方法;
@结束
然后
//MainController.h
#import "FooterBar.h"
@interface MainController : UIViewController <FooterBarDelegate> {
}
//MainController.h
#导入“FooterBar.h”
@接口主控制器:UIViewController{
}
您可以使用
self.parentViewController
它是指添加了当前可使用的viewController的viewController
self.parentViewController
它指的是添加当前viewController的viewController谢谢,Michal。我猜,你的答案是关于问题的第二部分(带页脚栏),对吗?如果是这样,那么第一个呢?我正在考虑按照您的答案重构第一个的代码。(在HeaderBar中创建并执行iAction,然后将其发送给MainViewController,如您的答案所示)是的,重构将是一个好主意。如果refreshHeader方法只使用Header执行作业,那么它应该属于它。然而,这可能不是必需的。这是你的决定,你必须权衡代码的简单性(可读性)和类之间的清晰关系。再次感谢你,Michal。我肯定会进行代码重构。真的需要这样做。这个应用程序一开始设计得不好。在我控制这个项目之前,主控制器曾经有1200行代码。现在,一切似乎都在正确的位置,一个接一个。祝你有美好的一天!!谢谢,迈克尔。我猜,你的答案是关于问题的第二部分(带页脚栏),对吗?如果是这样,那么第一个呢?我正在考虑按照您的答案重构第一个的代码。(在HeaderBar中创建并执行iAction,然后将其发送给MainViewController,如您的答案所示)是的,重构将是一个好主意。如果refreshHeader方法只使用Header执行作业,那么它应该属于它。然而,这可能不是必需的。这是你的决定,你必须权衡代码的简单性(可读性)和类之间的清晰关系。再次感谢你,Michal。我肯定会进行代码重构。真的需要这样做。这个应用程序一开始设计得不好。在我控制这个项目之前,主控制器曾经有1200行代码。现在,一切似乎都在正确的位置,一个接一个。祝你有美好的一天!!