Best way to safely clear data in a singleton?

梦想的初衷 提交于 2019-12-12 13:54:26

问题


I'm using a singleton called CSAppData to store data for my iPhone app. I'm storing an object called CSInbox in the singleton. When I logout of my app, I want to clear the data for that object.

Here is my singleton code, including the method for clearing the data:

- (id)init {
    self = [super init];
    if (self)
    {
        self.inbox = [[CSInbox alloc] init];
    }
    return self;
}

+ (CSAppData *)appData {
    static CSAppData * appDataInstance;
    @synchronized(self) {
        if(!appDataInstance) {
            appDataInstance = [[CSAppData alloc] init];
        }
    }
    return appDataInstance;
}

+(void) clearData {
    CSAppData *appData = [CSAppData appData];
    appData.inbox = [[CSInbox alloc] init];
}

However, in one of my view controllers, in the initWithCoder method, I'm storing the inbox variable:

-(id) initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if(self) {
        self.inbox = [[CSAppData appData] inbox];
    }
    return self;
}

So, when the app logs out and the clearData method is called, the view controller is still pointing to the old CSInbox object. And even though I am initializing a new view controller and setting it to the root view controller (in the AppDelegate), like this:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
MainTabControllerViewController *viewController = (MainTabControllerViewController *)[storyboard instantiateViewControllerWithIdentifier:@"mainView"];
[self.window setRootViewController:viewController];

The one child view controller that has the CSInbox is never reinitialized, and is still pointing to that old CSInbox object. (I'm not sure why this is happening.)

So, what is the best way to solve this?

  1. Change the clearData method in the singleton to just reset the properties of the CSInbox object, rather than alloc and init and new one?
  2. Move the self.inbox = [[CSAppData alloc] init]; to the viewDidLoad in the view controller class so it gets set properly upon the second login?
  3. Change the logout function in the AppDelegate so that the root view controller and all other view controllers are released, so they will reinitialize upon the second login?

I'm leaning toward #1 or #3...

As requested, here is CSInbox.h:

@interface CSInbox : NSObject

@property (nonatomic,strong) NSMutableArray *threads;
@property (nonatomic, assign) NSInteger newCount;
@property (nonatomic,strong) NSDate *lastUpdate;

-(void) setThreadsFromJSON:(NSDictionary *)json;

@end

And here is CSInboxViewController.h:

@interface CSInboxViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate, CSThreadViewControllerDelegate>

@property (strong, nonatomic) IBOutlet UITableView *inboxTableView;
@property (strong,nonatomic) CSInbox *inbox;

@end

And CSAppData.h:

@interface CSAppData : NSObject {
    CSInbox *inbox;
}

@property(nonatomic,strong) CSInbox *inbox;

+ (CSAppData *)appData;
+ (void)clearData;

@end

回答1:


I think the answer lies not in destroying the singleton object and recreating it, but to actually clear the instance variables within that singleton object.

You don't show the declaration of [CSAppData inbox], but if it's an NSMutableArray, for example, then you can clear that, and any existing references to the singleton object can remain:

+(void) clearData {
    CSAppData *appData = [CSAppData appData];
    [appData.inbox removeAllObjects];
}



回答2:


One way to handle this, complying with the spirit of using a singleton, is having your view controllers access directly your singleton inbox, i.e.: [CSAppData appData].inbox instead of self.inbox. This is a bit wordier, but it would "magically" fix your issue.

If that is not acceptable to you, I would go with option #1 of those you list. Even better, I would make the inbox in the singleton a singleton itself, or make sure it is never replaced by another instance.

EDIT:

Another approach you have, is using KVO in your controller so that it gets notified when the inbox object has changed. Don't know if it is quite worth it, but could be used.



来源:https://stackoverflow.com/questions/20150372/best-way-to-safely-clear-data-in-a-singleton

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!