Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 调用ViewController';从它的观点来看';s子视图?_Objective C_Ios_Ios4 - Fatal编程技术网

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行代码。现在,一切似乎都在正确的位置,一个接一个。祝你有美好的一天!!