我有超时功能,如果应用程序闲置(在后台)一段时间,我超时我的应用程序并将用户发送到登录屏幕。我在应用程序委托中将用户默认设置为“timedOut”的键设置为YES,然后在每个视图控制器中引用该键,如果为YES,则继续登录屏幕。在登录屏幕上,如果“timedOut”为YES,则会显示“会话超时”标签。我的问题是,如果我登录,然后很快注销,即使在显示标签后将该键明确设置为NO,然后同步用户默认值,也会显示标签。 如果我等待一两秒钟并注销,标签就会隐藏起来。我已经解决了“问题”,但想了解行为。NSUserDefaults没有快速更新值
来自视图的代码确实在我的登录视图控制器中加载。你可能会认为这会将isTimedOut更改为NO,但是当我执行快速注销时,viewdidload会再次被调用,但isTimedOut为YES。
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
sessionLabel.hidden = YES;
isTimedOut = [defaults boolForKey:@"isTimedOut"];
if (isTimedOut == YES)
{
sessionLabel.hidden = NO;
defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:NO forKey:@"isTimedOut"];
isTimedOut = NO;
NSLog(@"Timed Out has been reset to %s",[defaults boolForKey:@"isTimedOut"] ? "YES" : "NO");
[defaults synchronize];
}
UPDATE
我取代以上我的应用程序委托,而不是和NSUserDefaults的的“怪异”的行为走了使用属性的代码。
eONavAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
isTimedOut = appDelegate.isTimedOut;
sessionLabel.hidden = YES;
//isTimedOut = [defaults boolForKey:@"isTimedOut"];
NSLog(@"Timed Out has been reset to %s",appDelegate.isTimedOut ? "YES" : "NO");
if (isTimedOut == YES)
{
appDelegate.isTimedOut = NO;
sessionLabel.hidden = NO;
}
更多的代码
要注销,我有UIButtonBarItem调用SEGUE编程。 doLogout属性告诉登录视图控制器运行注销API。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:@"logoutSegue"])
{
// Get reference to the destination view controller
eoLoginViewController *vc = [segue destinationViewController];
vc.doLogout = YES;
}
}
isTimedOut设置在应用程序委托中的一个位置。
-(void)timeoutWithDate:(NSDate *)currentDate
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDate *previousDate = [defaults objectForKey:@"enteredBackground"];
NSTimeInterval distanceBetweenDates = [currentDate timeIntervalSinceDate:previousDate];//TimeInterval is in seconds
NSLog(@"Time between dates in seconds %f",distanceBetweenDates);
double minutesInAnHour = 60;
double minutesBetweenDates = distanceBetweenDates/minutesInAnHour;
NSLog(@"minutesBetweenDates %f",minutesBetweenDates);
if(minutesBetweenDates > 60)
{
isTimedOut = YES;
}
else
{
isTimedOut = NO;
}
}
不知道要了解清楚你的问题。但一个小问题:为什么不使用某种内存而不是userDefaults?这里有什么好处?如果我是你,我会在NSDate中存储“去背景”,然后在应用程序转到前景时进行比较。 – Vinzius 2013-02-15 23:17:29
提供完整的代码。至于目前尚不清楚发生了什么。每次调用同步时,NSUserDefaults都会将所有内容存储在内存中并保存为闪存,因此即使快速重新登录,也不应引起此类问题。 – 2013-02-17 02:47:02