最近我正在开发一个关于sqlite的应用程序。我使用FMDB(2.6.2),iOS使用10.2.0。数据库中有大约300万个项目。每个项目都有三个colomns:id
name
logo
。
当在UI上显示所有数据时,应用程序的要求是打击:
UITableView
或UICollectionView
滚动到底部来加载更多数据一样,但您仍然可以使用UITableView
或{{1} })根据要求,我测试了一些条件。
我可以满足第一个和第一个要求。但是最后一个,我发现当你从db中获取所有300万个项目一次或多次时,它仍然会导致内存溢出。
以下是我在后台队列中获取数据的代码:
UICollectionView
提示:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (_usersArrM.count < _countNum)
{
NSUInteger offset = _usersArrM.count + usersFromDBOffsetCount;
if (offset > _countNum)
{
offset = _countNum - _usersArrM.count;
}
else
{
offset = usersFromDBOffsetCount;
}
NSString *sql = [NSString stringWithFormat:@"select * from user limit %zd, %zd", _usersArrM.count, offset];
[_queue inDatabase:^(FMDatabase *db) {
FMResultSet *userModelRS = [db executeQuery:sql];
while (userModelRS.next)
{
AndyUserModel *userModel = [[AndyUserModel alloc] init];
userModel.Id = [userModelRS intForColumn:@"id"];
userModel.name = [userModelRS stringForColumn:@"name"];
userModel.logo = [userModelRS stringForColumn:@"logo"];
[_usersArrM addObject:userModel];
}
[userModelRS close];
}];
[_queue close];
}
});
:_usersArrM
数据源NSMutableAarray
UITableView
:db _countNum
:usersFromDBOffsetCount
static NSUInteger const usersFromDBOffsetCount = 2000;
:_queue
我想导致内存溢出的问题是_queue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
,即使_queue
,也不能正确释放关于db的一些内存。并且reult是循环的时候,app因内存问题而终止。
有一种方法可以在一个循环完成后完全释放db的内存。或者,满足这个应用程序的这些要求的正确方法是什么。
感谢。
答案 0 :(得分:0)
在某些时候,无论您的数据框架有多好,纯粹的内存分配都会使任何功能不足的硬件崩溃。您可以尝试挖空您想要检索的数据(即
SELECT specific_col_1, specific_col_2, ... FROM table WHERE conditions
其中specific_col_i
平均耗电量较低。
另一个安全措施是使用OFFSET
和LIMIT
来限制您在任何给定时间从数据库中提取的数据量:
SELECT specific_col_1, specific_col_2, ... FROM table WHERE conditions LIMIT x OFFSET j
其中x是一次提取和处理的安全记录数,j是检索到的最后一行数的索引。您可能需要使用x
和j
的值“播放”。
您可能必须使用智能循环算法来选择性地“引入并处理”所有这些记录。并且,如果需要,您可以将从循环中获得的批次存储到另一个表/数据库中(不确定数据处理时数据处理或数据引入后数据处理需要的确切内容)。 / p>
最后,您可能会发现LabQLite有帮助。这是我为在iOS应用程序中处理SQLite而开发的库。 LabQLite Model Generator是我创建的模型生成器,它允许您将表和视图视为Objective-C中的类(如果您使用互操作代码,则将Swift视为Swift))。 LabQLite还有大量的中低级数据库控制器方法,可能有助于改进我上面提到的循环/批处理过程。