简体   繁体   中英

How can appdelegate call the method of a viewcontroller?

My app consists of an appdelegate and several viewcontrollers.

A cron job is running (like fetching external data) in the appdelegate. When the data is updated, the appdelegate needs to update the datasource of one of the viewcontroller and then call the reloadData method from that viewcontroller?

Which approach should I use to solve the problem? Is NSNotification a good way? How about protocol or delegate?

Thanks.

I had the same requirement as you a few days ago. At first I went with the notifications, those that you post and receive using [NSNotificationCenter defaultCenter] . But I had problems with this approach, for some reasons I found this unreliable and hard to debug.

Then I implemented something like this: I have a class that handles all my custom notifications. This class keeps some arrays of observers, for example an array holds some view controllers which want to be notified of a certain event, another array holds some view controllers which want to be notified of another event, and so.

When you create your view controller that you want to be an observer of some event, you add the controller to the related array of this manager class.

And then, when an event happens in your app delegate, you tell this manager class to notify all the observer view controllers of this event. Then this manager class iterates in the related array and calls some certain methods of these observers. So, to do this, every view controller that's interested in the same event should have a public method with the same name, so that the notification manager can call this.

This can be improved of course, like having these view controllers that have the same interests implement a protocol, etc..

Here's a summary of what I mean. This is my notification manager class:

@interface NotificationUtility : NSObject

+(NSMutableArray *)getCallDurationObservers;
+(void)notifyCallDurationObservers;

@end

This is a part of the implementation:

#import "NotificationUtility.h"

static NSMutableArray *callDurationObservers = nil;

@implementation NotificationUtility

+(NSMutableArray *)getCallDurationObservers {
    if (callDurationObservers) {
        return callDurationObservers;
    }

    callDurationObservers = [[NSMutableArray alloc] init];
    return callDurationObservers;
}

+(void)notifyCallDurationObservers {
    for (TestViewController *observer in callDurationObservers) {
        [observer performSelector:@selector(updateCallDuration)];
    }
}

@end

And this is where I add my view controllers that are interested in observing call duration, to this manager's observers array:

- (void)arrangeCallDurationObservers {
    NSMutableArray *callDurationObservers = [NotificationUtility getCallDurationObservers];
    [callDurationObservers removeAllObjects];
    [callDurationObservers addObject:_detail];
    [callDurationObservers addObject:_callReport];
}

I would say use a delegate when there is a "master/slave" relationship (delegate knows about the class and class knows about the delegate), with one class higher up the control hierarchy, and when it is clear that there won't be situations where other elements (mostly UI) will be interested in knowing what the class has to say. Use notifications when the class is not interested in knowing who listens and how many they are, anybody and any number can register for the notifications.

我会与通知一起使用,以使您的代码减少耦合。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM