需要从另一个viewController调用其他viewControllers中的方法

时间:2013-01-02 22:34:44

标签: ios uiviewcontroller

我有一个具有多个viewControllers的应用程序,其中一些viewControllers包含运行各种任务的方法。我需要做的是当初始viewController加载时,是在其他viewControllers中调用这些方法使它们在后台运行,但是,我在执行此操作时遇到了一些困难。

假设我有4个viewControllers,A,B,C和& D,其中A是最初的viewController,在每个viewController中,我分别有aMethod,bMethod,cMethod和dMethod。以下是相关代码:

在我打开的viewController(AviewController)中:

<。>文件中的

#import "BViewController"
#import "CViewController"
#import "DViewController"

@interface AViewController:UIViewController {

BViewController *bViewCon;
CViewController *cViewCon;
DViewController *dViewCon;


}

@property (nonatomic, retain) BViewController *bViewCon;
@property (nonatomic, retain) CViewController *cViewCon;
@property (nonatomic, retain) DViewController *dViewCon;

@end

在我的.m文件中,我有以下内容:

#import "BViewController"
#import "CViewController"
#import "DViewController"

@implementation AviewController

@synthesize bViewCon, cViewCon, dViewCon;

- (void) viewDidLoad {

[super viewDidLoad];

bViewCon = [[BViewController alloc] init];
[bViewCon bMethod];

...

}

但是,我收到错误消息,“'BViewController'没有可见的@interface'声明选择器'bMethod'”。我需要从这个类中调用其他viewControllers中的其他方法(即AViewController)。

感谢所有回复的人。

2 个答案:

答案 0 :(得分:5)

您是否考虑过使用NSNotificationCenter?在通知上设置方法,并在需要它们时运行它们。如果您的其他视图控制器已实例化并可用,这有助于将其隐藏在导航控制器堆栈中或单独的选项卡上。

要回答关于该错误的问题,您需要在头文件中声明要调用的方法。该错误表明它无法找到该方法的声明。

通知中心示例

// listen for notifications - add to view controller doing the actions
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mySpecialMethod) name:@"SomeNotificationName" object:nil];

// when you want your other view controller to do something, post a notification
[[NSNotificationCenter defaultCenter] postNotificationName:@"SomeNotificationName" object:nil];

// you don't want this notification hanging around, so add this when you are done or in dealloc/viewDidUnload
[[NSNotificationCenter defaultCenter] removeObserver:self]; // this removes all notifications for this view
// if you want to remove just the one you created, you can remove it by name as well

答案 1 :(得分:1)

要解决您收到的错误,请确保在每个控制器的头文件(.h)中声明所有方法(否则,编译器将无法看到它们)。

由于所有这些控制器都是AViewController的子项(它们由AViewController创建并保存为ivars),因此我不会在此使用NSNotificationCenter(除非有其他控制器)在发生某些事件时需要通知的对象,这些对象不归AViewController所有。)

相反,我只是在你试图做的时候直接调用这些方法。

另一方面,如果这些方法正在启动正在进行的任务(在后台运行任务),则最好将方法调用移至init: AViewController方法。 (与iOS 5一样,视图可以卸载,因此可以多次调用viewDidLoad: ...例如,在内存警告和视图被屏蔽的情况下。我可能会做这样的事情:

- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle
{
    self = [super initWithNibName:nibName bundle:bundle];  // your correct stuff here
    if (self)
    {
         bViewCon = [[BViewController alloc] init];
         [bViewCon bMethod];
         // ... and so on for the other controllers
    }
    return self;
}

修改

虽然正如评论中所提到的,UIViewController在内存方面并不是很便宜......但老实说,最好重构一下这个代码来拥有一个单一的控制器({{{1}的子类1}}而不是NSObject,它更便宜)充当将在后台运行的任务的管理员。我想这可能会帮助你在以后的路上,因为它有助于划分每个控制器的任务和目的(在这种情况下,UIViewController应主要负责管理视图(/ view hierarchy in某些案例)和相关任务......如果正在进行的任务发生在与所述视图相关的事物范围之外,则可能表明UIViewController不应该处理它们......