I want to execute some codes with a time sequence like [5s, 10s, 10s, 20s], which means that it executes the code after 5 seconds, and executes it the second time after 10s. I want to use NSTimer, but I can not figure out how can I do.
Asked
Active
Viewed 131 times
0
-
possible duplicate of [How do I use NSTimer?](http://stackoverflow.com/questions/1449035/how-do-i-use-nstimer) – Josh Heald Nov 07 '14 at 10:40
-
`–performSelector:withObject:afterDelay:`, maybe? – holex Nov 07 '14 at 10:55
-
the time interval isn't the same – lixiaoyu Nov 07 '14 at 14:06
2 Answers
0
Create a data structure to hold the time intervals, the target and the action to execute:
(untested)
typedef struct {
NSTimeInterval interval;
id target;
SEL selector;
} ScheduledItem;
Then create an array of these items:
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]))
and then create a timer somewhere to dispatch the work:
@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];
}
You will most probably have to set-up the _schedule
array at runtime, as the target
won't be available at compile time. If it's always self
then you can leave it out of the schedule altogether and if you always call the same selector then you can leave that out too, leaving just an array of time intervals.

trojanfoe
- 120,358
- 21
- 212
- 242
0
My method is a bit simpler to implement.
- (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
});
}

Daniyar
- 2,975
- 2
- 26
- 39