Need to call methods in other viewControllers from

2019-02-28 17:30发布

I have an app that has multiple viewControllers, where some of these viewControllers contain methods that run various tasks. What I need to do is when the initial viewController loads, is to call these methods in the other viewControllers such that they run in the background, however, I am having some difficulty doing this.

Let's say I have 4 viewControllers, A, B, C, & D, where A is the initial viewController, and in each viewController, I have aMethod, bMethod, cMethod, and dMethod respectively. Here is the relevant code:

Inside my opening viewController (AviewController):

in the .h file:

#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

In my .m file I have the following:

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

@implementation AviewController

@synthesize bViewCon, cViewCon, dViewCon;

- (void) viewDidLoad {

[super viewDidLoad];

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

...

}

However, I am getting the error message, "No visible @interface for 'BViewController' declares the selector 'bMethod'". I need to call the other methods from the other viewControllers the same way from this class (i.e. AViewController).

Thanks in advance to all who reply.

2条回答
祖国的老花朵
2楼-- · 2019-02-28 18:03

To solve the error you're receiving, make sure that all of the methods are declared in the header (.h) files of each controller (otherwise, the compiler won't be able to see them).

As all of these controllers are children to AViewController (they are created by AViewController and kept as ivars on it), I wouldn't use NSNotificationCenter here (unless there are other objects that need to be notified in case of certain events occurring too, which aren't owned by AViewController).

Instead, I would just call the methods directly as you're attempting to do.

On another note, if these methods are starting ongoing tasks (running tasks in background), it may be best for you to move the method calls to the init: method of AViewController. (As on iOS 5, views CAN be unloaded and hence viewDidLoad: can be called potentially more than once... such as in the case of memory warnings and the view being off screened). I might go about doing something like this:

- (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;
}

Edit

Although, as mentioned in a comment, UIViewControllers aren't exactly cheap in terms of memory... it honestly would likely be best to refactor this code to have a single controller (a subclass of NSObject instead of UIViewController, which is cheaper) to act as a manager for the tasks that are going to be running in the background. I imagine this will likely help you later down the road too, as it would help compartmentalize the tasks and purpose of each of your controllers (in such, UIViewControllers should primarily be responsible for managing a view (/view hierarchy in some cases) and associated tasks... if there are ongoing tasks that are occurring outside the scope of things associated with said view, it's probably a sign that the UIViewController shouldn't be handling them...

查看更多
虎瘦雄心在
3楼-- · 2019-02-28 18:06

Have you considered using NSNotificationCenter? Set up the methods on the notifications and just ping them when you need them to run. This helps if your other view controller is instantiated and available, like buried in the navigation controller stack or on a separate tab.

To answer you question about that error, you need to declare the method you want to call in your header file. The error is stating it can't find a declaration for that method.

Example of notification center

// 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
查看更多
登录 后发表回答