从另一个方法中取消在循环中创建的所有 NSTimers

Cancel all NSTimers created in a loop from another method

为了将单元格添加到 TableView,我从一个循环中创建了很多计时器:

 for (NSInteger i = 0; i < media.products.count; i++) {
        NSDictionary *obj = [media.products objectAtIndex:i];
            NSInteger timeInterval = [[obj objectForKey:@"TIME"] integerValue];
            [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(addNewProductToTableView:) userInfo:obj repeats:NO];
    }

我想在显示另一个控制器时取消所有这些,在 shouldSelectViewController 或 viewWillDisappear 中是这样的:

  NSLog(@"I've been called!");
// Doesn't seem to work :
  [NSObject cancelPreviousPerformRequestsWithTarget:self]; 
  [NSTimer cancelPreviousPerformRequestsWithTarget:self]; 
// Clean the table
   self.dataSource = [NSMutableArray array];
   [self.tableView reloadData]; 

再次显示tableView时,前一个和当前计时器的混合使单元格显示混乱。

或者,如果它更简单,我不介意破坏整个控制器,但也无法让它工作。

self.view = nil; // ? 

cancelPreviousPerformRequestsWithTargetNSTimer无关。他们取消了与 performSelector:withObject:afterDelay:(及其伙伴 performSelector:withObject:afterDelay:inModes:)安排的通话。您需要做的是将您创建的计时器保留在 属性 中,并在需要取消时使其无效:

@protocol (nonatomic) NSTimer *timer;

...

self.timer = [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(addNewProductToTableView:) userInfo:obj repeats:NO];

...

[self.timer invalidate];
self.timer = nil;
  1. 在视图控制器的界面中创建NSMutableArray *timers;

  2. 在viewDidload中初始化分配timers = [[NSMutableArray alloc]init];

  3. 将循环代码更改为

    for (NSInteger i = 0; i < media.products.count; i++) { NSDictionary *obj = [media.products objectAtIndex:i]; NSInteger timeInterval = [[obj objectForKey:@"TIME"] integerValue]; NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(addNewProductToTableView:) userInfo:obj repeats:NO]; [timers addObject:timer]; }

以及任何你想要使计时器无效的地方

for (NSTimer *timer in timers)
    [timer invalidate];
}