需要从另一个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
在这里并不完全合适......主要原因是这些UIViewController
s 中的每一个都是AViewController
的孩子,所以它对@ 更有意义在我看来,987654326@ 直接在其子代上调用方法。
同意。问题是方法没有定义。如果只是执行方法的问题,是的,直接调用它们。如果这些视图中保存了数据并且您不想重新初始化,则通知会起作用。它们很简单,而且通常可以解决问题。【参考方案2】:
要解决您收到的错误,请确保在每个控制器的头 (.h) 文件中声明了所有方法(否则,编译器将无法看到它们)。
由于所有这些控制器都是 AViewController
的子级(它们是由 AViewController
创建并作为 ivars 保存在上面),我不会在这里使用 NSNotificationCenter
(除非有其他需要通知的对象以防发生某些不属于AViewController
的事件)。
相反,我会按照您的尝试直接调用这些方法。
另一方面,如果这些方法正在启动正在进行的任务(在后台运行任务),最好将方法调用移至AViewController
的init:
方法。 (在 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
s 在内存方面并不便宜......老实说,最好将这段代码重构为具有单个控制器(而不是 NSObject
的子类UIViewController
,更便宜)充当将在后台运行的任务的管理器。我想这也可能会在以后帮助您,因为它将有助于划分每个控制器的任务和目的(在这种情况下,UIViewController
s 应该主要负责管理视图(在某些情况下是 /view 层次结构) ) 和相关任务...如果正在进行的任务超出了与所述视图相关的范围,这可能表明UIViewController
不应该处理它们...
【讨论】:
以上是关于需要从另一个viewController调用其他viewController中的方法的主要内容,如果未能解决你的问题,请参考以下文章
从另一个 .swift 文件调用 ViewController 函数
UIWebView 在从另一个 ViewController 调用的方法中为 null