- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的应用程序出现问题,它在收集数据时 CPU 使用率飙升至 100% 以上。我已尽我所能控制处理过程,使其不会锁定设备,并继续获取所需的数据。
我们的客户有一些大型数据库,因此下载整个数据库是不可能的。我们还使用 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)
该字符串由以下方法创建,然后将其异步发送到服务器。我知道此方法中有一个问题,但我没有时间回过头来设计更好的解决方案。我正在使用 respondsToSelector 和 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];
}
}
如有任何帮助,我们将不胜感激!感谢您花时间查看。
最佳答案
是的。基本上黄金法则是:do not optimize prematurely .
但无论如何。我的第一个猜测是:将 NSString query
替换为 NSMutableString query
。因为您正在堆上创建 1500 个 NSString 对象,并且长度总是增加,只是为了在下一个循环中将它们扔掉。 NSMutalbeString 在附加时保持内存更长的时间 - 而且你总是在与同一个对象交谈。 '(然后使用 appendFormat
而不重新赋值,而不是使用 stringByAppendingFormat
赋值!)
看这里:Is NSMutableString's -appendString: method an efficient way to build up a large string?
关于iOS CPU 使用率飙升,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20455911/
我是一名优秀的程序员,十分优秀!