当我的应用程序第一次加载时,它将几个文本文件中的数据加载到SQLite数据库中。由于有大量数据,所以我将文件分割成几个较小的文件,并使用下面的代码在循环中加载数据。我在每次遍历时释放每个变量,并写入NSLog以记录当时的内存状态。即使我释放了内存正在减少的变量,我也收到了内存警告,1级和2级,然后应用程序关闭。会不会是向SQLite表中添加数据导致内存减少,或者我在代码中遗漏了什么?
while (filePathNo != @"7") {
NSString *filePath;
NSString *GenericName = nil;
.
.
// Nineteen Other Variables
.
.
if (filePathNo == @"1") {
filePath = [[NSBundle mainBundle] pathForResource:@"FileLoad1" ofType:@"txt"];
filePathNo = @"2";
}
else if (filePathNo == @"2") {
filePath = [[NSBundle mainBundle] pathForResource:@"FileLoad2" ofType:@"txt"];
filePathNo = @"3";
}
.
.
// Five Other Files declared
.
.
NSString *textFromFile = [NSString stringWithContentsOfFile:filePath];
NSString *cellString = textFromFile;
NSRange range2 = [cellString rangeOfString:@"<string>"];
range2 = [cellString rangeOfString:@"<string>"];
if (range2.location != NSNotFound ) {
eof = @"N";
cellString = [cellString substringFromIndex:range2.location + 8];
}
while (eof != @"Y") {
NSLog(@"Drug is - %@ , Memory free is %d", GenericName, [self get_freemem]);
progVal = progval + 1;
[self performSelectorOnMainThread:@selector(updateMyProgressBar) withObject:nil waitUntilDone:NO];
NSRange range1 = [cellString rangeOfString:@"#"];
if (range1.location != NSNotFound )
GenericName = [cellString substringToIndex:range1.location];
cellString = [cellString substringFromIndex:range1.location + 1];
.
.
// Find and load nineteen other variables
.
.
range2 = [cellString rangeOfString:@"</string>"];
if (range2.location != NSNotFound )
Doses = [cellString substringToIndex:range2.location];
cellString = [cellString substringFromIndex:range2.location + 9];
range2 = [cellString rangeOfString:@"<string>"];
if (range2.location != 0 ) {
eof = @"N";
@try {
cellString = [cellString substringFromIndex:range2.location + 8];
}
@catch (NSException *exception) {
eof = @"Y";
}
}
else {
eof = @"Y";
}
if (cellString == nil) {
eof = @"Y";
}
NSString *spkrs = @"";
char *errorMsg;
char *update = "INSERT OR REPLACE INTO DRUGTABLE (FullDrugName, GenericName, OtherNames, TradeName, PrescriptionStatus, Formulations, DrugAction, DrugUse, SafetyAndHandling, Contraindications, AdverseReactions, DrugInteractions, Therapeuticgroup, GeneralAction, SpecificAction, ChemicalGroup, DrugReferences, Furtherreading, Doses) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
//int errVal = sqlite3_prepare_v2(database, update, -1, &stmt, nil);
if (sqlite3_prepare_v2(database, update, -1, &stmt, nil) == SQLITE_OK);
{
sqlite3_bind_text(stmt, 1, [FullDrugName UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 2, [GenericName UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 3, [OtherNames UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 4, [TradeName UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 5, [PrescriptionStatus UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 6, [Formulations UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 7, [DrugAction UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 8, [DrugUse UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 9, [SafetyAndHandling UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 10, [Contraindications UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 11, [AdverseReactions UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 12, [DrugInteractions UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 13, [Therapeuticgroup UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 14, [GeneralAction UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 15, [SpecificAction UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 16, [ChemicalGroup UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 17, [References UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 18, [FurtherReading UTF8String], -1, NULL);
sqlite3_bind_text(stmt, 19, [Doses UTF8String], -1, NULL);
}
if (sqlite3_step(stmt) != SQLITE_DONE)
{
NSString *err = errorMsg;
}
sqlite3_finalize(stmt);
[spkrs release];
}
[GenericName release];
.
.
// Release all nineteen other variables
.
.
}发布于 2011-05-09 20:50:11
我认为你应该做的是把一个NSAutoReleasePool放在你的循环之外,然后不时地drain它。你可能在你的循环中创建了自动释放对象,这是一个漏洞。例如,cellString = [cellString substringFromIndex:range1.location + 1];
发布于 2011-05-09 20:42:50
除了最后的[spkrs release]和[GenericName release]之外,我在这段代码中看不到任何发布调用。
您是否尝试过使用Xcode附带的分析器来构建项目?它可以为您提供许多有用的信息,包括哪些对象正在泄漏、在哪里泄漏以及为什么泄漏。
使用性能工具-> Leaks通过Run -> Start尝试
发布于 2011-05-09 22:32:00
你不应该发布GenericString或者spkrs,因为你从来没有alloc或者retain过它们。实际上,我不确定为什么要有一个spkrs变量,因为它看起来不像是用来做任何事情的。
https://stackoverflow.com/questions/5936168
复制相似问题