2013-01-31 29 views
4

下面的代码工作,但有一个错误。情景是,我开始登录进入应用程序系统。一旦登录成功,应用程序将设置UserDefaults(UserId)。之后,我可以使用存储的UserId导航应用视图。一旦我转到设置和标签注销,这将清除UserId并进入登录视图。什么是从IOS应用程序注销的完美方式?

该错误:当我再次登录到应用程序,然后单击主页按钮转到iPhone桌面并关闭应用程序,并返回打开它,它仍然存储UserId。所以,如果我去设置并注销将清除UserId并不会去登录视图。我不知道为什么。

代码:

- (IBAction)resetKeychain:(id)sender { 

    UIActionSheet *actionSheet = [[UIActionSheet alloc] 
       initWithTitle:@"Are you sure you want to logout?" 
       delegate:self 
       cancelButtonTitle:@"Cancel" 
       destructiveButtonTitle:@"Logout" 
       otherButtonTitles:nil]; 
    actionSheet.actionSheetStyle = UIActionSheetStyleDefault; 
    [actionSheet showFromTabBar:self.tabBarController.tabBar]; 
    [actionSheet release]; 

} 

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { 
    if (buttonIndex ==0) { 
     //logout 
     NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; 
     //delete user ID fro user Defaults 
     [defaults setObject:nil forKey:@"UserId"]; 
     //redirect to login view 

     NewClassMoonAppDelegate * appsDelegate =[[UIApplication sharedApplication] delegate]; 
     [appsDelegate.window addSubview:[appsDelegate.login view]]; 

    } 
} 
+2

有没有这样的事,作为一个“完美的解决方案。”请记住,最好的是善的敌人。 – Eric

+0

好吧,埃里克,谢谢 –

回答

8

从我可以解释从你的问题,这需要格式化和方式作出连贯,笔者认为:

一)你@"UserID"值与NSUserDefaults不同步,因为您没有调用-synchronize方法。 NSUserDefaults将更新其内存中的键值存储,但不会将其写入磁盘,这意味着它在任意时间丢失。

b)事实上它不会去loginView可能是由于几个原因,最有可能的是它已经是你的UIWindow的子视图。因此,请不要在应用程序代理中重复使用login属性,而应创建一个新的实例变量View Controller,并将其设置为rootViewController

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { 

    if (buttonIndex == 0) { 
     NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; 
     [defaults setObject:nil forKey:@"UserId"]; 
     [defaults synchronize]; 
     //redirect to login view 

     NewClassMoonAppDelegate * appsDelegate =[[UIApplication sharedApplication] delegate]; 
     LoginViewController *login = [[LoginViewController alloc] initWithNibName...]; 
     [appsDelegate.window setRootViewController:nil]; 
     [appsDelegate.window setRootViewController:login]; 

    } 
} 
+0

是的,现在我清楚你的观点,谢谢它工作正常。 –

+0

嗨max_,你的解决方案很好,但我确实有疑问,我需要从登录出应用程序之前加载的内存中删除所有其他MVC的吗?如果不是那些MVC发生了什么?他们会记忆吗?应该如何处理这种情况? – RockandRoll

+0

由rootViewController和rootViewController本身提供的任何内容都将从内存中释放。这不会立即发生,因为您可能在应用程序的其他地方保留了引用,或者编译器可能没有做好准备。 –

0

斯威夫特

MAX_的回答有了一些变化:

let objectsToSave: [String] = [obj1, obj2, obj3] 
for key in objectsToSave { 
    NSUserDefaults.standardUserDefaults().removeObjectForKey(key) 
} 

let appsDelegate = UIApplication.sharedApplication().delegate 
let storyboard = UIStoryboard(name: "MainStoryboard", bundle: nil) 
let newLoginVC: LoginViewController = storyboard.instantiateInitialViewController() as! LoginViewController 
appsDelegate?.window!!.rootViewController = nil 
appsDelegate?.window!!.rootViewController = newLoginVC 

编辑:只有我所做的更改只是,我通过故事板初始化newLoginVC而不是initWitName

+0

请详细解释一下,为什么改变以及你用它来实现什么。 – davejal

0

让UINavigation控制器的性能和合成它,并写下面的代码在注销按钮

AppDelegate * appDelegateObj =[[UIApplication sharedApplication] delegate]; 
    login *loginObj = [[login alloc]initWithNibName:@"login" bundle:nil]; 
    [appDelegateObj.window setRootViewController:nil]; 
    navObj=[[UINavigationController alloc]initWithRootViewController:loginObj]; 
    [appDelegateObj.window setRootViewController:navObj]; 
+0

为什么需要'UINavigationController'? OP不在导航堆栈中显示登录控制器。除此之外,我没有看到已经发布的其他答案的任何补充。 – UditS

相关问题