首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >正在释放变量,但应用程序仍会泄漏内存并崩溃

正在释放变量,但应用程序仍会泄漏内存并崩溃
EN

Stack Overflow用户
提问于 2011-05-09 19:21:14
回答 4查看 240关注 0票数 0

当我的应用程序第一次加载时,它将几个文本文件中的数据加载到SQLite数据库中。由于有大量数据,所以我将文件分割成几个较小的文件,并使用下面的代码在循环中加载数据。我在每次遍历时释放每个变量,并写入NSLog以记录当时的内存状态。即使我释放了内存正在减少的变量,我也收到了内存警告,1级和2级,然后应用程序关闭。会不会是向SQLite表中添加数据导致内存减少,或者我在代码中遗漏了什么?

代码语言:javascript
复制
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
      .
      .
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-05-09 20:50:11

我认为你应该做的是把一个NSAutoReleasePool放在你的循环之外,然后不时地drain它。你可能在你的循环中创建了自动释放对象,这是一个漏洞。例如,cellString = [cellString substringFromIndex:range1.location + 1];

票数 1
EN

Stack Overflow用户

发布于 2011-05-09 20:42:50

除了最后的[spkrs release][GenericName release]之外,我在这段代码中看不到任何发布调用。

您是否尝试过使用Xcode附带的分析器来构建项目?它可以为您提供许多有用的信息,包括哪些对象正在泄漏、在哪里泄漏以及为什么泄漏。

使用性能工具-> Leaks通过Run -> Start尝试

票数 0
EN

Stack Overflow用户

发布于 2011-05-09 22:32:00

你不应该发布GenericString或者spkrs,因为你从来没有alloc或者retain过它们。实际上,我不确定为什么要有一个spkrs变量,因为它看起来不像是用来做任何事情的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5936168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档