我以编程方式构建我的TabBar
,并根据用户是否登录,我设置
[self.window setRootViewController:home];
以下是我调用的代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
if (![Persistence loggedIn])
{
[self showLoginScreen];
}
else
{
SignupBase *login = [STLoginSignupBase new];
[login loginUserwithUsername:[Persistence username] andPassword:[Persistence authPass] requestByNewUser:NO completionBlock:^(NSError *error)
{
if (!error)
{
[login loginSuccess];
[self showTabBarScreen];
}
else
{
[STAlertViewUtils showAlert:@"" :error.localizedDescription :kButtonTitleDismiss];
[self showLoginScreen];
}
}];
}
-(void)showTabBarScreen
{
dispatch_async(dispatch_get_main_queue(), ^{
TabBarVC *tabBarVC = [[TabBarVC alloc]init];
[self.window setRootViewController:tabBarVC];
});
}
-(void)showLoginScreen
{
dispatch_async(dispatch_get_main_queue(), ^{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"STLoginSignup" bundle:nil];
HomeVC *homeVC = (HomeVC *)[storyboard instantiateViewControllerWithIdentifier:[HomeVC storyboardID]];
UINavigationController *home = [[UINavigationController alloc]initWithRootViewController:homeVC];
[self.window setRootViewController:home];
});
}
在TabBar
,第一个标签"收件箱"是一个使用NSFetchedResultsController
管理的tableViewController。当我第一次启动应用程序时,所有对象都被提取并在tableView中显示得很漂亮;但是,当我退出并重新登录时,"收件箱"重新加载,我得到一个空白的tableView。零对象在本地获取,即使RESTkit提取对象,它们也不会出现在tableView中。当我在模拟器中停止应用程序并重新启动它时,所有对象都在本地和远程获取,并在应该出现在tableView中!
以下是我从Profile
标签(不同标签)注销的方式:
- (void)logoutWithCompletionBlock:(void(^)(void))completionBlock
{
[Persistence setLoggedInStatus:NO];
RKObjectManager *objectManager = [self getObjectManager];
[objectManager.HTTPClient clearAuthorizationHeader];
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = delegate.managedObjectStore.mainQueueManagedObjectContext;
[managedObjectContext reset];
[delegate deregisterWithUrbanAirship];
if (completionBlock)
{
completionBlock();
}
}
在我重新登录应用程序后,"收件箱"选项卡viewController再次加载。
在我的"收件箱"调用loadView,我有以下代码:
- (void)loadView
{
[self getManagedObjectFromAppDelegate]
}
- (void)getManagedObjectFromAppDelegate
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate setupCoreDataWithRESTKit];
self.objectManager = [self getObjectManager];
self.objectManager.managedObjectStore = appDelegate.managedObjectStore;
self.objectManager.managedObjectStore.managedObjectCache = appDelegate.managedObjectStore.managedObjectCache;
self.managedObjectContext = self.objectManager.managedObjectStore.mainQueueManagedObjectContext;
}
这是[AppDelegate setupCoreDataWithRESTKit];
- (RKManagedObjectStore *)setupCoreDataWithRESTKit
{
NSError * error;
NSURL * modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"App" ofType:@"momd"]];
NSManagedObjectModel * managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
self.managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
[self.managedObjectStore createPersistentStoreCoordinator];
NSArray * searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentPath = [searchPaths objectAtIndex:0];
NSPersistentStore * persistentStore = [self.managedObjectStore addSQLitePersistentStoreAtPath:[NSString stringWithFormat:@"%@/App%@.sqlite", documentPath, [Persistence username]] fromSeedDatabaseAtPath:nil withConfiguration:nil options:[self optionsForSqliteStore] error:&error];
NSAssert(persistentStore, @"Failed to add persistent store with error: %@", error);
NSLog(@"Path: %@", [NSString stringWithFormat:@"%@/App%@.sqlite", documentPath, [Persistence username]]);
if(!persistentStore){
NSLog(@"Failed to add persistent store: %@", error);
}
[self.managedObjectStore createManagedObjectContexts];
return self.managedObjectStore;
}
请注意,每个用户都根据用户名加载了不同的.sqlite文件:即AppUserName。因此,当我注销并重新登录时,如果它是同一个用户,则创建/加载相同的文件。如果它是不同的用户,则创建/加载不同的名称文件。
问题:为什么在我退出并重新登录后NSFetchedResultsController
显示一个空的tableView,但是当我第一次启动应用程序时它可以正常工作?
*编辑*
我改变并尝试了下面的代码,但问题仍然存在:
- (void)logoutWithCompletionBlock:(void(^)(void))completionBlock
{
[Persistence setLoggedInStatus:NO];
RKObjectManager *objectManager = [self getObjectManager];
[objectManager.HTTPClient clearAuthorizationHeader];
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = delegate.managedObjectStore.mainQueueManagedObjectContext;
[self clearManagedObjectContext:managedObjectContext];
[delegate deregisterWithUrbanAirship];
if (completionBlock)
{
completionBlock();
}
}
- (void)clearManagedObjectContext:(NSManagedObjectContext*)managedObjectContext
{
NSFetchRequest * fetch = [[NSFetchRequest alloc] init];
[fetch setEntity:[NSEntityDescription entityForName:@"EntityA" inManagedObjectContext:managedObjectContext]];
NSMutableArray *result = [NSMutableArray arrayWithArray:[managedObjectContext executeFetchRequest:fetch error:nil]];
for (id entityA in result)
{
[managedObjectContext deleteObject:entityA];
}
[result removeAllObjects];
[fetch setEntity:[NSEntityDescription entityForName:@"EntityB" inManagedObjectContext:managedObjectContext]];
result = [NSMutableArray arrayWithArray:[managedObjectContext executeFetchRequest:fetch error:nil]];
for (id entityB in result)
{
[managedObjectContext deleteObject:entityB];
}
[result removeAllObjects];
[fetch setEntity:[NSEntityDescription entityForName:@"EntityC" inManagedObjectContext:managedObjectContext]];
result = [NSMutableArray arrayWithArray:[managedObjectContext executeFetchRequest:fetch error:nil]];
for (id entityC in result)
{
[managedObjectContext deleteObject:entityC];
}
[result removeAllObjects];
[managedObjectContext saveToPersistentStore:nil];
}
答案 0 :(得分:1)
除非您拆除支持主线程上下文的持久存储(因此,拆除整个Core Data堆栈并销毁SQLite文件),否则不应该执行[managedObjectContext reset];
。
要么纠正这个问题,要么只是在上下文中循环删除要删除的内容,并将更改保存到(父)持久化上下文中。