【发布时间】:2013-07-10 01:32:51
【问题描述】:
这个错误在我的代码中已经存在好几天了 - 我一直在尝试解决它,但无济于事。我已经在模拟器和设备上进行了广泛的调试、日志记录、Crashlytics 抛出崩溃日志,这与我的 NSTimer 在解除分配后发送消息有关。我会进一步解释。
这个NSTimer 控制我在某些视图控制器上的UIToolbar 标签,它不断更新标签以显示从用户刷新UITableView 开始的相对时间。加载时,每次刷新时,它都会显示Updated just now,然后如果用户不刷新/转到另一个 VC,它会每 60 秒更新一次。因此,一分钟后,它将显示Updated 1 minute ago。 NSTimer 触发一个执行 UILabel 更新的方法。在用户刷新时(通过拉动刷新控件),此方法在我的getAllItems 中手动调用(这就是我传递nil 的原因)。
我的NSTimer 在我的超类中定义为:
@property (nonatomic, weak) NSTimer *updateDateTimer;
这是将项目放入我的表格视图的代码:
- (void)getAllItems
{
KILL_TIMER(self.updateDateTimer);
self.updateLabel = [Formatters boldLabelWithLabel:self.updateLabel
withText:@"Checking for items..."
withFont:[UIFont fontWithName:kOpenSansBold size:15.0f]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self fetchObjectsWithRequest:self.request];
sleep(1);
dispatch_async(dispatch_get_main_queue(), ^{
[self.refreshControl performSelector:@selector(endRefreshing) withObject:nil afterDelay:0];
self.updatedDate = [NSDate date];
[self updateTimer:nil];
self.updateDateTimer = [NSTimer scheduledTimerWithTimeInterval:kToolbarUpdateLabelInterval
target:self
selector:@selector(updateTimer:)
userInfo:nil repeats:YES];
});
});
}
KILL_TIMER(q) 在我的超类中定义为:
#define KILL_TIMER(q) if (q) {DDLogVerbose(@"KILLING TIMER: %@", q); [q invalidate]; q=nil;}
此定义在 2 种方法中调用:
a) 在我的getAllItems 方法中:所以当我(重新)加载项目时(通过在viewDidLoad 中调用该方法或通过用户刷新表格视图),我总是尝试终止当前处于活动状态的计时器,显示“检查项目”,获取项目,显示“刚刚更新”,然后安排计时器每 60 秒执行一次。
b) 在每个 viewWillDisappear 上,例如:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
KILL_TIMER(self.updateDateTimer);
}
但是,如果我点击主页按钮,然后重新打开应用程序,它通常(并非总是,仅当我切换视图控制器时)崩溃并显示以下消息(启用 NSZombies):
2013-07-11 17:21:37.576 App[3923:907] *** -[ItemCDTVC setUpdateDateTimer:]: message sent to deallocated instance 0x20bc49f0
我确实有一个NSNotification 调用我的getAllItems:
// Notification received when user returns to app (refreshes the table view)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getAllItems) name:UIApplicationWillEnterForegroundNotification object:nil];
这只发生在我使用菜单切换视图控制器、离开应用程序并重新打开(应用程序不会终止)之后。 如果用户留在应用程序中,无论他们在多少个视图控制器之间切换,它都不会崩溃。
这是一个非常烦人的错误,因为虽然它很容易重现,但我不知道如何修复它。任何帮助表示赞赏。
【问题讨论】:
-
什么时候取消控制器的观察者身份?
-
@Wain 你是说这个吗?
[[NSNotificationCenter defaultCenter] removeObserver:self];?如果是这样,我已将此代码放在dealloc。 -
好,在上面打个断点,看看什么时候命中。
-
@Wain
dealloc在我选择一个不是我当前的 VC 的菜单项(加载另一个视图控制器)后立即被调用。 -
您已经在
getAllItems上放置了一个断点,以查看它在您的崩溃场景中是如何调用的?
标签: ios objective-c crash nstimer memory-management