TAGS :Viewed: 8 - Published at: a few seconds ago

[ How to invalidate NSTimer Which one runing in loop? ]

I want to play sound in different schedule like Every 3 , Every 5, after 9,after 22 .....etc, so I create a for loop and and pass different -2 scheduledTimerWithTimeInterval like this .

    -(void)bellsSchedual{

        arrBellsListAllData=[EMeditationDBModel getDataFromBellsList:prop.userId];
        EMeditationDBProperty *bellProp=[[EMeditationDBProperty alloc]init];
       for (int i=0; i<arrBellsListAllData.count; i++)
       {
        bellProp=[arrBellsListAllData objectAtIndex:i];

        NSString *bellsTime=bellProp.bTime;
        if ([bellProp.bTimeSchedule isEqualToString:@"after"]) {

               bellTimer= [NSTimer scheduledTimerWithTimeInterval:          [bellsTime intValue] target: self
                                                         selector: @selector(playSound:) userInfo:nil repeats: NO];

}
  else if ([bellProp.bTimeSchedule isEqualToString:@"every"]){

        bellTimer=[NSTimer scheduledTimerWithTimeInterval:[bellsTime intValue] target: self
                                                         selector: @selector(playSound:) userInfo:nil repeats: YES]; 

        }
   }
}

problem is that my timer is not invalidate.if for loop run only once that time timer invalidate .

Answer 1


I think you should go with the approach of array of NSTimers

Somewhere, mostly in your viewDidLoad

NSMutableArray *arrTimers = [[NSMutableArray alloc] init]

In your code

for (int i=0; i<arrBellsListAllData.count; i++)
{
    bellProp=[arrBellsListAllData objectAtIndex:i];
    NSString *bellsTime=bellProp.bTime;
    if ([bellProp.bTimeSchedule isEqualToString:@"after"]) {

         NSTimer *bellTimer= [NSTimer scheduledTimerWithTimeInterval:[bellsTime intValue] target: self
                                                         selector: @selector(playSound:) userInfo:nil repeats: NO]

        [arrTimers addObject:bellTimer];
    }
    else if ([bellProp.bTimeSchedule isEqualToString:@"every"]){

         NSTimer *bellTimer=[NSTimer scheduledTimerWithTimeInterval:[bellsTime intValue] target: self
                                                         selector: @selector(playSound:) userInfo:nil repeats: YES];
         [arrTimers addObject:bellTimer]; 

    }
}

Invalidate by looping

-(void) invalidateAllTimers{
    for( NSTimer *timer in arrTimers) {
       [timer invalidate];
    }
}

If you want to invalidate a particular timer then use

[NSTimer scheduledTimerWithTimeInterval:[bellsTime intValue]
                                             target:self
                                           selector:@selector(playSound:)
                                           userInfo:anyId
                                            repeats:NO];

Where pass any identifier in userInfo object to find any specific timer.

Answer 2


    -(void)bellsSchedual {

    arrBellsListAllData = [EMeditationDBModel getDataFromBellsList:prop.userId];
    EMeditationDBProperty *bellProp = [[EMeditationDBProperty alloc] init];
    for (int i=0; i<arrBellsListAllData.count; i++) {
        bellProp = [arrBellsListAllData objectAtIndex:i];
        NSString *bellsTime = bellProp.bTime;
        if ([bellProp.bTimeSchedule isEqualToString:@"after"]) {
            [NSTimer scheduledTimerWithTimeInterval:[bellsTime intValue]
                                             target:self
                                           selector:@selector(playSound:)
                                           userInfo:nil
                                            repeats:NO];
        } else if ([bellProp.bTimeSchedule isEqualToString:@"every"]){
            [NSTimer scheduledTimerWithTimeInterval:[bellsTime intValue] target: self
                                             target:self
                                           selector:@selector(playSound:)
                                           userInfo:nil
                                            repeats:YES];
        }
    }
}