2013-01-31 55 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

相關問題