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

Posted

技术标签:

【中文标题】需要从另一个viewController调用其他viewController中的方法【英文标题】:Need to call methods in other viewControllers from another viewController 【发布时间】:2013-01-02 22:34:44 【问题描述】:

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

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

在我打开的viewController(AviewController)里面:

在 .h 文件中:

#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'”。我需要从这个类(即 AViewController)以相同的方式从其他 viewController 调用其他方法。

提前感谢所有回复的人。

【问题讨论】:

小心创建所有这些视图控制器,就像你正在做的那样......UIViewController 在内存使用方面并不便宜......你是否考虑过创建单个管理器控制器(而不是NSObject 的子类,哪个更便宜)来处理所有所说的背景任务? 很遗憾,没有,现在回去重新设计应用程序已经太晚了。 听起来你可能需要考虑重构。 这是一个秘密答案。您不需要在其他视图控制器中调用方法。你一定要重新设计应用程序,因为这个问题迟早会追上你,而且修复起来会更加困难。 【参考方案1】:

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

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

通知中心示例

// 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

【讨论】:

非常感谢您的及时回复。我从来没有使用过 NSNotificationCenter,你能给我举个例子吗? 有没有办法使用 NSNotificationCenter 并按照我上面显示的方式直接调用方法? 你把方法签名放在viewcontroller的.h文件里了吗?例如。在 BViewController.h 中有一行写着“-(void)bMethod;”其中 void 被替换为函数返回的任何内容。这些签名是你可以让其他类知道一个类可以做什么的方式。 我认为NSNotificationCenter 在这里并不完全合适......主要原因是这些UIViewControllers 中的每一个都是AViewController 的孩子,所以它对@ 更有意义在我看来,987654326@ 直接在其子代上调用方法。 同意。问题是方法没有定义。如果只是执行方法的问题,是的,直接调用它们。如果这些视图中保存了数据并且您不想重新初始化,则通知会起作用。它们很简单,而且通常可以解决问题。【参考方案2】:

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

由于所有这些控制器都是 AViewController 的子级(它们是由 AViewController 创建并作为 ivars 保存在上面),我不会在这里使用 NSNotificationCenter(除非有其他需要通知的对象以防发生某些不属于AViewController 的事件)。

相反,我会按照您的尝试直接调用这些方法。

另一方面,如果这些方法正在启动正在进行的任务(在后台运行任务),最好将方法调用移至AViewControllerinit: 方法。 (在 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;

编辑

虽然,正如评论中提到的,UIViewControllers 在内存方面并不便宜......老实说,最好将这段代码重构为具有单个控制器(而不是 NSObject 的子类UIViewController,更便宜)充当将在后台运行的任务的管理器。我想这也可能会在以后帮助您,因为它将有助于划分每个控制器的任务和目的(在这种情况下,UIViewControllers 应该主要负责管理视图(在某些情况下是 /view 层次结构) ) 和相关任务...如果正在进行的任务超出了与所述视图相关的范围,这可能表明UIViewController 不应该处理它们...

【讨论】:

以上是关于需要从另一个viewController调用其他viewController中的方法的主要内容,如果未能解决你的问题,请参考以下文章

从另一个 .swift 文件调用 ViewController 函数

UIWebView 在从另一个 ViewController 调用的方法中为 null

快速从另一个 ViewController 调用函数

从其他项目推送 ViewController 时出错

当从另一个 ViewController 类调用方法时,Xcode 找到一个 nil 变量,其中不应该是任何变量

使用 UIView 中的按钮从另一个 ViewController 触发方法