在iOS中按时间顺序执行任务

在iOS中按时间顺序执行任务,ios,objective-c,nstimer,Ios,Objective C,Nstimer,我想执行一些时间序列的代码,比如[5s,10s,10s,20s],这意味着它在5秒后执行代码,在10秒后第二次执行。我想使用NSTimer,但我不知道该怎么做。创建一个数据结构来保存时间间隔、目标和要执行的操作: (未经测试) 然后创建以下项目的数组: static ScheduledItem _schedule[] = { { 5.0, someTarget, @selector(someMethod) }, { 10.0, someTarget, @selector(some

我想执行一些时间序列的代码,比如[5s,10s,10s,20s],这意味着它在5秒后执行代码,在10秒后第二次执行。我想使用NSTimer,但我不知道该怎么做。

创建一个数据结构来保存时间间隔、目标和要执行的操作:

(未经测试)

然后创建以下项目的数组:

static ScheduledItem _schedule[] = {
    { 5.0, someTarget, @selector(someMethod) },
    { 10.0, someTarget, @selector(someMethod) },
    { 15.0, someTarget, @selector(someMethod) }
};
#define NUM_SCHEDULED_ITEMS (sizeof(schedule) / sizeof(schedule[0]))
然后在某处创建计时器以分派工作:

@interface MyClass ()
{
    NSTimer *_timer;
    unsigned _scheduledItem;
}
- (void)_setupTimer;
- (void)_timerFired:(NSTimer *)timer;
@end

@interface MyClass

- (instancetype)init
{
    self = [super init];
    if (self) {
        _scheduledItem = 0;
        [self _setupTimer];
    }
    return self;
}

- (void)_setupTimer
{
    _timer = nil;
    if (_scheduledItem < NUM_SCHEDULED_ITEMS) {
        NSTimeInterval interval = _schedule[_scheduledItem].interval
        _timer = [NSTimer scheduledTimerWithTimeInterval:interval
                                                  target:self
                                                selector:@selector(_timerFired:)
                                                userInfo:nil
                                                 repeats:NO];
    }
}

- (void)_timerFired:(NSTimer *)timer
{
    id target = _schedule[_scheduledItem].target;
    SEL action = _schedule[_scheduleItem].action;
    [target performSelector:action withObject:nil];
    _scheduledItem++;
    [self _setupTimer];
}
@接口MyClass()
{
NSTimer*\u定时器;
未签名的_scheduledItem;
}
-(无效)_;
-(无效)_timerFired:(n计时器*)计时器;
@结束
@接口MyClass
-(instancetype)初始化
{
self=[super init];
如果(自我){
_scheduledItem=0;
[自动设置计时器];
}
回归自我;
}
-(无效)
{
_定时器=零;
if(_scheduledItem

您很可能必须在运行时设置
\u调度
数组,因为
目标
在编译时不可用。如果它总是
self
,那么您可以将其完全排除在计划之外,如果您总是调用同一个选择器,那么您也可以将其排除在外,只留下一组时间间隔。

我的方法实现起来更简单一些

- (void)startExecute
  { 
    intervals=@[@(5),@(10),@(10),@(20)]; // class member
    isExecuting=YES; // class member
    [self executeTaskAtIndex:0]; // start first task
  }

- (void)executeTaskAtIndex:(NSUInteger)index
  { 
   if (index>=intervals.count || !isExecuting) // no intervals left or reset execution
       return;
   NSNumber *intervalNumber=intervals[index];
   NSTimeInterval interval=intervalNumber.doubleValue;
   dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(interval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
      if(!isExecuting)
         return;
      // execute your task here
      //...
      index++;
      [self executeTaskAtIndex:index]; // another iteration
   });
  }

可能重复
–PerformSelect:withObject:afterDelay:
,时间间隔不一样
- (void)startExecute
  { 
    intervals=@[@(5),@(10),@(10),@(20)]; // class member
    isExecuting=YES; // class member
    [self executeTaskAtIndex:0]; // start first task
  }

- (void)executeTaskAtIndex:(NSUInteger)index
  { 
   if (index>=intervals.count || !isExecuting) // no intervals left or reset execution
       return;
   NSNumber *intervalNumber=intervals[index];
   NSTimeInterval interval=intervalNumber.doubleValue;
   dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(interval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
      if(!isExecuting)
         return;
      // execute your task here
      //...
      index++;
      [self executeTaskAtIndex:index]; // another iteration
   });
  }