title: iOS CPU usage skyrockets here
body: <p>I have an issue with my app where it spikes up to over 100% CPU usage when gathering data.  I have done everything I can think of to reign in the processing so that it doesn't lock the device up, and still continues to get the data that's needed.</p>
  
  <p>Our customers have some big databases, so downloading the entire database is out the question.  We are also using REMObjects as middleware, so I have to work with that.  What I did was figure out what data was needed for the user, and setup a series of calls to gather that information.  I think that where my problem lies is in the fact that the database can only process up to 1500 items in a call.</p>
  
  <p>Here is a sample query string that is getting sent to the server.</p>
  
  <pre><code>SELECT COMMUNICATIONID, PHONEEXTENTION, PHONEDESC, PHONETIMETOCALL, PHONENUMBER 
  FROM PHONE WHERE COMMUNICATIONID IN (3761, 3793, 5530, 4957, 4320, 1914, 3715, 6199, 5548,
  5580, 5994, 5867, 1437, 4943, 6217, 3765, 2442, 227, 4084, 977, 6822, 5680, 263, 4502, 
  327, 6112, 136, 7053, 5571, 6958, 6799, 5525, 6530, 4779, 604, 2182, 6198, 3792, 6071, 
  4383, 5866, 7444, 1309, 226, 4083, 5916, 1295, 626, 1249, 1950, 2141, 3369, 326, 135, 
  6780, 5411, 5938, 4424, 6034, 649, 6179, 5861, 4778, 5479, 2181, 6197, 3791, 5815, 6070, 
  6420, 7935, 4542, 4319, 6679, 4942, 4082, 4974, 5533, 5788, 5597, 976, 3764, 1917, 6202, 
  134, 6779, 3768, 5410, 5665, 7880, 7052, 6033, 5492, 6815, 3118, 4218, 5110, 6529, 6115, 
  6069, 348, 4318, 4382, 1498, 6406, 4941, 7443, 2376, 4623, 5755, 5532, 6201, 6392, 625, 
  7270, 4977, 6396, 6524, 5664, 7051, 725, 6032, 6701, 6160, 5491, 5937, 6273, 1875, 6114, 
  5477, 6528, 5573, 4936, 6705, 2180, 3758, 5527, 5368, 5814, 7328, 7424, 429, 5991, 1434, 
  6391, 6200, 7283, 5868, 5900, 228, 4085, 6109, 1106, 5791, 692, 6095, 7210, 2893, 1188, 
  6814, 4217, 5572, 3757, 5813, 3694, 796, 605, 6486, 128, 4144, 5722, 5754, 1915, 5676, 
  5549, 5581, 4976, 5917, 5822, 2174, 6158, 1633, 4566, 5267, 4885, 4503, 1874, 6113, 5476, 
  4425, 4871, 5526, 6531, 7886, 1496, 5194, 127, 4780, 5721)
  </code></pre>
  
  <p>That string is created by the following method, which then sends it asynchronously to the server.  There is one issue in this method that I know is a problem, but I haven't had the time to circle  back to it and devise a better solution.  I am using respondsToSelector and performSelector to process additional methods based on the table that we're gathering details from.</p>
  
  <pre><code>- (void)processRequest
  {
      if( requestQueue.count == 0 )
          return;
  
      if( processingQueue.count &gt; 3 )
          return;
  
      Request *request = requestQueue[0];
      [requestQueue removeObjectAtIndex:0];
      DADataTable *source = request.source;
      NSString *destTableName = request.destTableName;
      NSString *sourceKey = request.sourceKey;
      NSString *query = request.query;
      NSArray *destKeys = request.destKeys;
      NSString *originMethodName = request.originMethodName;
      NSArray *destinationMethods = request.destinationMethods;
      NSString *message = request.loadingMessage;
  
      [[NSNotificationCenter defaultCenter] postNotificationName:@"GATHERINGDATA" object:nil];
  
  
      // Cycle through the rows in the source table and extract the keys we need.
      // originMethodName is needed because some tables require additional checks
      // to determine what kind of key we are working with
      // sourceKey is the string that holds the key we're looking for, which is
      // used on tables that don't need specific filtering
      NSSet *set = [self getSourceSet:source originMethodName:originMethodName sourceKey:sourceKey];
  
      // getLists takes the set generated by getSourceSet and converts the list of
      // ids into a comma separated list of items suitable for passing into a query
      // Currently there is a 1400 item limit per list to keep from exceeding the server
      // limit, which is currently 1500
      NSArray *lists = [self getLists:set];
  
      NSString *msg = @"Loading Data";
      NSLog(@"%@", message);
      for( NSString *tList in lists ) {
          if( tList.length == 0 ) {
               NSLog(@"%@ not needed", originMethodName);
               continue;
          }
  
          query = [query stringByAppendingFormat:@"%@)", tList];
  
          NSLog(@"%@: %@", destTableName, query);
          DAAsyncRequest __block *r = [fda beginGetDataTableWithSQL:query withBlock:^(DADataTable *table){
               DADataTable *destination = [tables valueForKey:destTableName];
               if( tables.count == 0 ) destination = table;
               else if( [destination rowCount] &gt; 0 )
                  //dispatch_async(queue, ^(){
                  [destination mergeTable:table withPrimaryKeys:destKeys];
                  //});
  
               else
                  destination = table;
  
               [[NSUserDefaults standardUserDefaults] setValue:msg forKey:@"LoadingMessage"];
               [[NSNotificationCenter defaultCenter] postNotificationName:InitialViewControllerNotificationLoadingUpdate object:nil];
               [[NSNotificationCenter defaultCenter] postNotificationName:@"UpdateStatus" object:nil];
  
               //dispatch_async(queue, ^(){
               [tables setValue:destination forKey:destTableName];
               //});
  
               for( NSString *method in destinationMethods) {
                  SEL tMethod = NSSelectorFromString(method);
                  if( [self respondsToSelector:tMethod]) {
                      [self performSelector:tMethod withObject:table];
                  }
               }
  
  
               if( [self busy] &amp;&amp;
                   [[source name] isEqualToString:DataAccessTableCustomer])
               {
                  [[NSUserDefaults standardUserDefaults] setValue:nil forKey:@"FETCHINGJOB"];
                  [[NSNotificationCenter defaultCenter] postNotificationName:@"JOBFETCHED" object:nil];
               }
               if( [[[NSUserDefaults standardUserDefaults] valueForKey:@"FETCHINGCONTACT"] isEqualToString:@"YES"] &amp;&amp;
                  ([[source name] isEqualToString:DataAccessTablePerson] ||
                   [[source name] isEqualToString:DataAccessTableOrganization] ||
                   [[source name] isEqualToString:DataAccessTableOrganizationAddress]))
              {
                   [[NSUserDefaults standardUserDefaults] setValue:nil forKey:@"FETCHINGCONTACT"];
                   [[NSNotificationCenter defaultCenter] postNotificationName:@"CONTACTFETCHED" object:nil];
              }
              [processingQueue removeObject:r];
              [[NSNotificationCenter defaultCenter] postNotificationName:@"PROCESSREQUEST" object:nil];
          }];
          [processingQueue addObject:r];
      }
  }
  </code></pre>
  
  <p>Any help here will be greatly appreciated!  Thanks for taking the time to look.</p>