【发布时间】:2016-05-12 14:42:28
【问题描述】:
我已经能够在我们的应用程序中重现两次缺陷,但大多数时候我都失败了。所以我试图了解这里可能发生的事情,并希望有一些新的东西可以尝试。我们的应用程序超时并在 10 分钟后使用 NSTimer 将用户注销。每次触摸屏幕都会重置计时器,这一切都很好。
当用户后台应用程序并返回时,会调用以下代码:
- (BOOL)sessionShouldTimeOut {
if (self.timeoutManager) {
NSTimeInterval timeIntervalSinceNow = [self.timeoutManager.updateTimer.fireDate timeIntervalSinceDate:[NSDate date]];
if (timeIntervalSinceNow < 0) {
return YES;
} else {
return NO;
}
}
return NO;
}
- (void)timeoutIfSessionShouldTimeOut {
if ([self sessionShouldTimeOut]) {
[self.timeoutManager sendNotificationForTimeout];
}
}
这(我怀疑)是失败的代码。当它失败时会发生什么是用户登录,点击主页并锁定他们的手机。 10 多分钟后,他们解锁并且应用程序未注销。当他们回来时,会执行上面的代码来注销用户,但在某些情况下它会失败 - 让用户在不应该出现的情况下仍然在主页上。
这是我目前正在尝试测试的理论:
计时器以某种方式在后台触发,然后运行注销例程,但由于我们在后台,UI 没有更新但计时器无效(我们在注销后使计时器无效)我'我不确定应用程序在前台后是否会显示从后台调用的 UI 代码,因此这可能是不可能的。
用户实际上是在计时器触发前几秒钟回来的,然后在它应该触发的几秒钟后它没有回来,因为它已在后台运行了 10 分钟。如果应用进入后台,计时器是否会继续达到原来的触发时间?
不知何故,在后台,
self.timeoutManager、updateTimer或fireDate被释放并设置为 nil,导致sessionShouldTimeOut方法返回NO。变量可以在后台取消吗?如果可以,他们会怎样?当手机需要一段时间才能真正移动到应用程序时,会运行注销例程,从而可能导致 UI 更新无法反映?
我对其他理论非常开放,因为你可以看到我的很多理论都是非常极端的情况,因为我完全不确定发生了什么。
我很感激任何人都可以提供关于我可以尝试的其他方法的任何指导,或者甚至是对 NSTimer 或 NSRunLoop 的底层工作的任何见解,这可能在这种情况下会有所帮助(关于这些的文档对于我的问题)
【问题讨论】:
-
重要的是要知道
self.timeoutManager != nil是不是,如果是,那么fireDate的NSTimer是什么。更多的日志记录应该这样做。 -
您能想出一个场景,它会导致
self.timeoutManager和fireDate在后台被清除吗?内存不足,还是其他类型的场景可能导致 iOS 释放这些对象?因为正常。逻辑工作得很好,self.timeoutManager不是 nil,fireDate距离最后一次触摸还有 10 分钟,它可以正常注销,这只是在我试图确定的某种非常具体的情况下。 -
不,对象不应该在后台释放,所以我想不是那样的。