简体   繁体   中英

How can i add a custom delegate method to my singleton

I am developing a digital magazine reader app and it requires to download magazines first. While downloading them i want to pass download progress data between viewcontrollers. That's why i am using singleton design pattern. I also use NSNotification to update progressBar percentage while its downloading. But i do not think it is quite efficient to send notificiation in every milisecond. So i decided to use delegate design pattern but i don't know to implement a custom delagete method. Any help on custom delegate? And is it the best way to use delegate?

// Header

@interface ZXCSingleton : NSObject

+ (id)sharedInstance;

- (BOOL)isDownloadingProduct:(NSString *)productID;
- (void)addToDownloadListWithProductID:(NSString *)productID;
- (void)removeFromDownloadListWithProductID:(NSString *)productID;
- (NSArray *)getDownloadList;

- (void)setDownloadProgress:(float)progress
              withProductID:(NSString *)productID;
- (float)getDownloadProgressWithProductID:(NSString *)productID;

@end

// M

#import "ZXCSingleton.h"

@implementation ZXCSingleton{
    NSMutableArray *downloadList;
    NSMutableDictionary *downloadProgress;
}

+ (id)sharedInstance
{
    static ZXCSingleton *sharedInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        sharedInstance = [[ZXCSingleton alloc] init];
    });
    return sharedInstance;
}

- (id)init
{
    self = [super init];
    if (self) {
        downloadList        = [[NSMutableArray alloc] init];
        downloadProgress    = [[NSMutableDictionary alloc] init];
    }
    return self;
}

- (BOOL)isDownloadingProduct:(NSString *)productID
{
    for (int i = 0; i < downloadList.count; i++) {
        if ([[downloadList objectAtIndex:i] isEqualToString:productID]) return YES;
    }
    return NO;
}

- (void)addToDownloadListWithProductID:(NSString *)productID
{
    [downloadList addObject:productID];
}

- (void)removeFromDownloadListWithProductID:(NSString *)productID
{
    [downloadList removeObject:productID];
}

- (NSArray *)getDownloadList
{
    return downloadList;
}

- (void)setDownloadProgress:(float)progress
              withProductID:(NSString *)productID
{
    if (progress != [[downloadProgress objectForKey:productID] floatValue]) [[NSNotificationCenter defaultCenter] postNotificationName:@"downloading" object:nil];
    [downloadProgress setObject:[NSString stringWithFormat:@"%0.2f", progress] forKey:productID];
}

- (float)getDownloadProgressWithProductID:(NSString *)productID
{
    return [[downloadProgress objectForKey:productID] floatValue];
}

Define a delegate by creating a protocol first for defining the interface required by the delegate :

@protocol ZXCSingletonProtocol 

   - (void)downloadProgessUpdates:(float)progress;

@end

Create a property for the delegate in your singleton :

@property (nonatomic, weak) id<ZXCSingletonProtocol> delegate; 

Let your view controller conform to that protocol :

@interface MyViewController : UIViewController <ZXCSingletonProtocol>

and implement the downloadProgessUpdates in the view controller as required (eg update the UI element with the given progress number). REMEMBER to set the delegate when you initialize the view controller ( viewDidLoad will do):

[ZXCSingleton sharedInstance].delegate = self; // self is the view controller instance

In your singleton update the setDownloadProgress method to update the delegate as well :

[_delegate downloadProgessUpdates:progress];

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