Reputation: 773
I have some timer code to invoke a AFNetworking 2.0 POST every 2.5 seconds. After experimentation with Xcode simulator and the actual iPhone, I found that on the iPhone, it takes about 5-6seconds before commands are sent out successfully to the server. As a result, the commands called every 2.5 seconds get piled up. On the Xcode simulator, there is no such problem. Commands return the success block in less than a second.
More background: The aim of POSTing every 2.5 seconds is to keep the TCP connection open. This way, the calls are made even faster compared to opening a new connection every time.
One reason for the lag could be due to the main thread getting too many requests. I have several methods which in turn call more methods. My question: Should I just use a single custom concurrent queue, or multiple custom concurrent queues? Is this even a good way to solve the networking problem I am facing?
Note: I currently use self.commandSent to track and ensure not too many commands are sent out before the previous POSTs are completed. Will be changing to dispatch groups for this purpose.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self startTimer];
}
-(void)startTimer
{
dispatch_async(self.myConcurrentQueue, ^{
self.startTime = CFAbsoluteTimeGetCurrent() ;
self.displayTimer = [NSTimer scheduledTimerWithTimeInterval:2.5 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES ] ;
});
}
-(void)timerFired:(NSTimer*)timer
{
//Should I use another dispatch thread here?
CFAbsoluteTime elapsedTime = CFAbsoluteTimeGetCurrent() - self.startTime ;
[self updateDisplay:elapsedTime] ;
}
-(void)stopTimer
{
[self.displayTimer invalidate] ;
self.displayTimer = nil ;
CFAbsoluteTime elapsedTime = CFAbsoluteTimeGetCurrent() - self.startTime ;
[self updateDisplay:elapsedTime] ;
}
-(void)updateDisplay:(CFAbsoluteTime)elapsedTime
{
[self maintainConnection];
}
- (void)maintainConnection {
//Should I use another dispatch thread here?
if (self.commandSent == YES ) {
if(self.temperatureChanged == YES) {
[self updateTemperature]; //updateTemperature and updateSpeed are similar. They call POST requests
[self updateSpeed];
self.temperatureChanged = NO;
} else {
[self updateSpeed];
}
}
}
- (void)updateSpeed {
self.commandSent = NO;
NSURL *baseURL = [NSURL URLWithString:self.BaseURLString];
NSDictionary *parameters = @{@"command": @"16",
@"dat": self.dataToSend,};
//Create instance of AFHTTPSessionManager and set response to default JSON
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:@"submit" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
self.commandSent = YES;
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"%@", [error localizedDescription]);
}];
}
Upvotes: 1
Views: 320
Reputation: 131418
AFNetworking is an async API built on top of Apples NSURLConnection and NSURLSession classes. It handles the background processes for you, and you should not try to add threading on top of the async logic already built into the library.
Concurrent programming can make certain tasks faster because on a multi-core system, you get all available cores doing part of a job at the same time, like having multiple workers building a house instead of just one.
Like building a house, though, there are dependencies. You can't pour the foundation until the sewer pipe and utility feeds are in place. You can't build the frame until the foundation is poured. You can't put the roof on until the walls are up. You can't hang drywall until the roof is on and the house is water-tight.
Similarly, when you break a computer task up to run it concurrently, there are often inter-dependencies between the tasks. In graphics processing, you have to do your vertex calculations first before you can render textures onto the resulting surfaces.
Your questions tell me that you don't really understand the concepts behind concurrent programming. There be dragons! Concurrent programming is very tricky business, the number of ways you can screw it up, large and small, are almost infinite, and the resulting problems are very difficult to diagnose and fix.
If you don't know about race conditions, locks, spin locks, semaphores, and such, stay away from concurrent programing. You will wind up with an unstable mess.
Upvotes: 1