このバグは私のコードに何日もありました - 私はそれを解決しようとしましたが、役に立ちませんでした. シミュレーターとデバイス、ログ、Crashlytics がクラッシュ ログをスローする広範なデバッグを行いました。これは、NSTimer
割り当て解除後にメッセージが送信されたことに関係しています。さらに説明します。
これにより、一部のビュー コントローラーでラベルがNSTimer
制御され、UIToolbar
ラベルが更新され続けて、ユーザーがUITableView
. 読み込み時、および更新のたびに表示さUpdated just now
れ、ユーザーが更新しない/別の VC に移動しない場合、60 秒ごとに更新され続けます。そのため、1 分後に が表示されUpdated 1 minute ago
ます。は、更新NSTimer
を行うメソッドをトリガーします。UILabel
ユーザーが更新すると (更新コントロールをプルすることによって)、このメソッドは my 内で手動で呼び出されますgetAllItems
(そのため、 を渡しnil
ます)。
MyNSTimer
はスーパークラスで次のように定義されています。
@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
か、ユーザーがテーブル ビューを更新することによって)、常にアクティブな現在のタイマーを強制終了し、「アイテムのチェック」を表示し、アイテム、'updated just now' を表示し、タイマーを 60 秒ごとに実行するようにスケジュールします。
b)各viewWillDisappear`で、次のように:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
KILL_TIMER(self.updateDateTimer);
}
ただし、ホームボタンを押してアプリを再度開くと、通常は (常にではありませんが、View Controller を切り替えた場合のみ)、次のメッセージが表示されてクラッシュします (NSZombies が有効になっている場合)。
2013-07-11 17:21:37.576 App[3923:907] *** -[ItemCDTVC setUpdateDateTimer:]: message sent to deallocated instance 0x20bc49f0
私NSNotification
は my を呼び出すを持っていますgetAllItems
:
// Notification received when user returns to app (refreshes the table view)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getAllItems) name:UIApplicationWillEnterForegroundNotification object:nil];
これは、メニューを使用してView Controllerを切り替え、アプリを終了して再度開いた後にのみ発生します(アプリは終了しません)。ユーザーが切り替えたView Controllerの数に関係なく、ユーザーがアプリにとどまってもクラッシュしません。
非常に厄介なバグです。非常に簡単に再現できますが、修正方法がわからないからです。どんな助けでも大歓迎です。