在单例中安全清除数据的最佳方法?

Tre*_*man 3 singleton objective-c ios

我正在使用一个名为CSAppData我的iPhone应用程序存储数据的单例.我正在存储一个CSInbox在单例中调用的对象.当我注销我的应用程序时,我想清除该对象的数据.

这是我的单例代码,包括清除数据的方法:

- (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];
}
Run Code Online (Sandbox Code Playgroud)

但是,在我的一个视图控制器中,在initWithCoder方法中,我存储了收件箱变量:

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

因此,当应用程序注销并clearData调用该方法时,视图控制器仍指向旧CSInbox对象.即使我正在初始化一个新的视图控制器并将其设置为根视图控制器(在AppDelegate中),如下所示:

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

具有的子视图控制器CSInbox永远不会重新初始化,并且仍然指向旧的CSInbox对象.(我不确定为什么会这样.)

那么,解决这个问题的最佳方法是什么?

  1. 更改clearData单例中的方法只是重置CSInbox对象的属性,而不是alloc和init和new?
  2. 移动self.inbox = [[CSAppData alloc] init];viewDidLoad视图控制器类中,以便在第二次登录时正确设置?
  3. 更改注销功能,AppDelegate以便释放根视图控制器和所有其他视图控制器,以便在第二次登录时重新初始化?

我倾向于#1或#3 ......

根据要求,这是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
Run Code Online (Sandbox Code Playgroud)

这是CSInboxViewController.h:

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

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

@end
Run Code Online (Sandbox Code Playgroud)

CSAppData.h:

@interface CSAppData : NSObject {
    CSInbox *inbox;
}

@property(nonatomic,strong) CSInbox *inbox;

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

@end
Run Code Online (Sandbox Code Playgroud)

tro*_*foe 5

我认为答案不在于破坏单例对象并重新创建它,而是要实际清除该单例对象中的实例变量.

您没有显示声明[CSAppData inbox],但是如果它是NSMutableArray,例如,那么您可以清除它,并且对单例对象的任何现有引用都可以保留:

+(void) clearData {
    CSAppData *appData = [CSAppData appData];
    [appData.inbox removeAllObjects];
}
Run Code Online (Sandbox Code Playgroud)