我正在使用一个名为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];
}
但是,在我的一个视图控制器中,在initWithCoder
方法中,我存储了收件箱变量:
-(id) initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if(self) {
self.inbox = [[CSAppData appData] inbox];
}
return self;
}
因此,当应用程序注销并调用clearData
方法时,视图控制器仍指向旧的CSInbox
对象。即使我正在初始化一个新的视图控制器并将其设置为根视图控制器(在AppDelegate中),如下所示:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
MainTabControllerViewController *viewController = (MainTabControllerViewController *)[storyboard instantiateViewControllerWithIdentifier:@"mainView"];
[self.window setRootViewController:viewController];
具有CSInbox
的一个子视图控制器永远不会重新初始化,并且仍然指向旧的CSInbox对象。 (我不确定为什么会这样。)
那么,解决这个问题的最佳方法是什么?
clearData
方法,只重置CSInbox
对象的属性,而不是alloc和init以及新对象?self.inbox = [[CSAppData alloc] init];
移动到视图控制器类中的viewDidLoad
,以便在第二次登录时正确设置?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
这是 CSInboxViewController.h :
@interface CSInboxViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate, CSThreadViewControllerDelegate>
@property (strong, nonatomic) IBOutlet UITableView *inboxTableView;
@property (strong,nonatomic) CSInbox *inbox;
@end
CSAppData.h :
@interface CSAppData : NSObject {
CSInbox *inbox;
}
@property(nonatomic,strong) CSInbox *inbox;
+ (CSAppData *)appData;
+ (void)clearData;
@end
答案 0 :(得分:5)
我认为答案不在于破坏单例对象并重新创建它,而是实际清除该单例对象中的实例变量。
您没有显示[CSAppData inbox]
的声明,但是如果它是NSMutableArray
,那么您可以清除它,并且可以保留对单例对象的任何现有引用:
+(void) clearData {
CSAppData *appData = [CSAppData appData];
[appData.inbox removeAllObjects];
}
答案 1 :(得分:1)
处理此问题的一种方法是遵守使用单身人士的精神,让您的视图控制器直接访问您的单身inbox
,即:[CSAppData appData].inbox
而不是self.inbox
。这有点啰嗦,但它会“神奇地”修复你的问题。
如果您不接受,我会选择您列出的选项#1。更好的是,我会将单例中的inbox
变为单身,或者确保它永远不会被另一个实例替换。
编辑:
您拥有的另一种方法是在控制器中使用KVO,以便在inbox
对象发生更改时收到通知。不知道它是否值得,但可以使用。