У меня проблема с моим приложением, где она накапливается до 100% использования ЦП при сборе данных. Я сделал все, о чем я могу думать, чтобы править в процессе обработки, чтобы он не блокировал устройство и все еще продолжает получать нужные данные.iOS Использование CPU skyrockets здесь
У наших клиентов есть несколько больших баз данных, поэтому загрузка всей базы данных не возникает. Мы также используем REMObjects в качестве промежуточного ПО, поэтому я должен работать с этим. То, что я сделал, это выяснить, какие данные необходимы пользователю, и настроить серию вызовов для сбора этой информации. Я думаю, что, где моя проблема заключается в том, что база данных может обрабатывать до 1500 элементов в вызове.
Ниже приведен пример строки запроса, отправляемой на сервер.
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)
Эта строка создается следующим методом, который затем асинхронно отправляет его на сервер. В этом методе есть одна проблема, которая, как я знаю, является проблемой, но у меня не было времени вернуться к ней и разработать лучшее решение. Я использую responsesToSelector и performSelector для обработки дополнительных методов на основе таблицы, с которой мы собираем данные.
- (void)processRequest
{
if(requestQueue.count == 0)
return;
if(processingQueue.count > 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] > 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] &&
[[source name] isEqualToString:DataAccessTableCustomer])
{
[[NSUserDefaults standardUserDefaults] setValue:nil forKey:@"FETCHINGJOB"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"JOBFETCHED" object:nil];
}
if([[[NSUserDefaults standardUserDefaults] valueForKey:@"FETCHINGCONTACT"] isEqualToString:@"YES"] &&
([[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];
}
}
Любая помощь здесь будет принята с благодарностью! Спасибо, что нашли время посмотреть.
Нам нужна дополнительная информация, которая вам поможет. Запускаете ли вы свой код с помощью инструмента профилирования времени? Это укажет вам на код, который занимает наибольшее время процессора. –