Question

I cannot seem to work this one out. Here is my set up:

I have a function called requestDataWithCompletion:(someBlock)block. I call it when the class is initialised. The function requests certain motion data. I want to do this periodically, therefore, the first time I call this function, I specify some completion code which sets up a timer that re-calls this function periodically. The timer calls it via another function requestDataWithoutCompletion which simply calls the requestDataWithCompletion but with an empty block (so I don't keep creating timers);

- (void) requestDataWithCompletion:(someBlock)block {
// BREAK POINT 1
        [self.motionManager queryActivityStartingFromDate:start toDate:[NSDate date] toQueue:self.queue withHandler:^(NSArray *activities, NSError *error) { 
// BREAK POINT 2
            // do some processing; 
            block();
        }];
    }

The block simply creates a timer on the main queue, which periodically recalls this function, but with no completion (since I don't want to keep creating more timers).

block = ^{
      dispatch_async(dispatch_get_main_queue(), ^{
            self.timer = [NSTimer scheduledTimerWithTimeInterval:timerInterval 
target:self selector:@selector(requestDataWithoutCompletion) userInfo:nil repeats:YES];
            });
    }

- (void) requestDataWithoutCompletion {
[self requestDataWithCompletion^{;}];
}

The amazing thing is that despite this set up, my app is creating timer after timer! I can't understand why.

I have placed break points in requestDataWithCompletion method. One is outside the block submitted to NSOperationQueue to get activity data (BREAKPOINT 1) and one is inside the block submitted to NSOperationQueue. (BREAKPOINT 2). Basically it shows that each time the method is called by the timer, BREAKPOINT 1 has an empty completion block (as it should be) but then strangely BREAKPOINT 2 has the completion block I submitted when I first called the function when initialising the class. Therefore, it continues to create a new timer each time the function is called by the timer. Over time, this means a massive number of timers and then the app crashes!

I have a feeling this is something to do with NSOperationQueue, but I really don't know what it could be.

Était-ce utile?

La solution

In your initialisation (or when you first want to get the data and then continue getting it):

self.timer = [NSTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selector(requestDataWithoutCompletion) userInfo:nil repeats:YES];
[self.timer fire]; //get the activity data immediately. 

- (void) requestDataWithoutCompletion {
    [self requestDataWithCompletion:^{}];
}

With your original requestDataWithCompletion: method. (though you could get rid of requestDataWithCompletion: and put it's code directly in requestDataWithoutCompletion if you're not using it elsewhere)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top