2011-12-26 156 views
0

我在我的應用程序中有內存分配問題。這導致我的程序被凍結並最終導致結束。回顧我的代碼,我意識到大部分內存分配都在CFString中。以下是導致此問題的類。分配內存

#import "iMAPProdutosPesquisar.h" 
#import "iMAPArrayProdutos.h" 
#import "iMAPTabela.h" 
#import "iMAPProdutosFiltro.h" 
#import "iMAPArrayAbreviatura.h" 

static NSString *dadosProdutos = nil; 

@implementation iMAPProdutosPesquisar 

@synthesize pop; 
@synthesize tv; 
@synthesize sb; 
@synthesize datBaseName; 
@synthesize datBasePath; 
@synthesize iMAP; 
@synthesize abrev; 
@synthesize opcFil; 
@synthesize cab; 
@synthesize cons; 

#define TAG_1 1 
#define TAG_2 2 
#define TAG_3 3 

#define FIRST_CELL_IDENTIFIER @"TrailItemCell" 
#define SECOND_CELL_IDENTIFIER @"RegularCell" 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 

    if (self) { 

     // Custom initialization 
    } 

    return self; 
} 

- (void)dealloc { 

    [pop release]; 
    [tv release]; 
    [sb release]; 
    [datBaseName release]; 
    [datBasePath release]; 
    [iMAP release]; 
    [abrev release]; 
    [opcFil release]; 
    [cab release]; 
    [cons release]; 
    [super dealloc]; 
} 

- (void)didReceiveMemoryWarning { 

    // Releases the view if it doesn't have a superview. 
    [super didReceiveMemoryWarning]; 

    // Release any cached data, images, etc that aren't in use. 
} 

#pragma mark - View lifecycle 

- (void)viewDidLoad { 

    [super viewDidLoad]; 

    // Do any additional setup after loading the view from its nib. 
    [self initDatBase]; 

    [cab setImage:[UIImage imageNamed:@"cabecalho-produtos.png"]]; 
    cab.opaque = YES; 
} 

- (void)viewDidUnload { 

    [self setPop:nil]; 
    [self setTv:nil]; 
    [self setSb:nil]; 
    [self setDatBaseName:nil]; 
    [self setDatBasePath:nil]; 
    [self setIMAP:nil]; 
    [self setAbrev:nil]; 
    [self setOpcFil:nil]; 
    [self setCab:nil]; 
    [self setCons:nil]; 
    [super viewDidUnload]; 

    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 

    // Return YES for supported orientations 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

#pragma mark UISearchBarDelegate 

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { 

    [self initDatBase]; 
} 

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { 

    [searchBar resignFirstResponder]; 
} 

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { 

    [searchBar resignFirstResponder]; 
} 

#pragma mark tableView delegates 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 

    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 

    tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; 

    return [iMAP count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    iMAPArrayProdutos *arrayProd = (iMAPArrayProdutos *)[iMAP objectAtIndex:indexPath.row]; 

    NSString *myIdent = @"myIdent"; 

    iMAPTabela *tab = (iMAPTabela *)[tableView dequeueReusableCellWithIdentifier:myIdent]; 

    tv.autoresizesSubviews = YES; 

    if (tab == nil) { 

     tab = [[[iMAPTabela alloc] initWithFrame:CGRectZero reuseIdentifier:myIdent] autorelease]; 

     UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(10.0, 0, 150.0, tableView.rowHeight)] autorelease]; 

     [tab addColumn:170]; 

     label.tag = TAG_1; 
     label.font = [UIFont systemFontOfSize:14.0]; 
     label.text = arrayProd.cod; 
     label.textAlignment = UITextAlignmentLeft; 
     label.textColor = [UIColor blackColor]; 
     label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight; 

     [tab.contentView addSubview:label]; 

     label = [[[UILabel alloc] initWithFrame:CGRectMake(180.0, 0, 150.0, tableView.rowHeight)] autorelease]; 

     [tab addColumn:340]; 

     label.tag = TAG_2; 
     label.font = [UIFont systemFontOfSize:14.0]; 
     label.text = arrayProd.artrf2; 
     label.textAlignment = UITextAlignmentLeft; 
     label.textColor = [UIColor blackColor]; 
     label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight; 

     [tab.contentView addSubview:label]; 

     label = [[[UILabel alloc] initWithFrame:CGRectMake(350.0, 0, 418.0, tableView.rowHeight)] autorelease]; 

     [tab addColumn:768]; 

     label.tag = TAG_3; 
     label.font = [UIFont systemFontOfSize:14.0]; 
     label.text = arrayProd.descri;  
     label.textAlignment = UITextAlignmentLeft; 
     label.textColor = [UIColor blackColor]; 
     label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight; 

     [tab.contentView addSubview:label]; 
    } 

    UILabel *label_1 = (UILabel *)[tab.contentView viewWithTag:TAG_1]; 
    label_1.text = arrayProd.cod; 

    UILabel *label_2 = (UILabel *)[tab.contentView viewWithTag:TAG_2]; 
    label_2.text = arrayProd.artrf2; 

    UILabel *label_3 = (UILabel *)[tab.contentView viewWithTag:TAG_3]; 
    label_3.text = arrayProd.descri; 

    return tab; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    iMAPArrayProdutos *arrayProd = (iMAPArrayProdutos *)[iMAP objectAtIndex:indexPath.row]; 

    [iMAPProdutosPesquisar setDefaultValue:[NSString stringWithFormat:@"%@", arrayProd.cod]]; 
} 

- (IBAction)fil:(id)sender { 

    iMAPProdutosFiltro *prodFil = [[iMAPProdutosFiltro alloc] init]; 
    pop = [[UIPopoverController alloc] initWithContentViewController:prodFil]; 

    prodFil.pop = pop; 

    [prodFil release]; 

    [pop setPopoverContentSize:CGSizeMake(170, 220)]; 
    [pop presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 
} 

- (void)initDatBase { 

    datBaseName = @"iMAP.sqlite"; 

    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDir = [documentPaths objectAtIndex:0]; 

    datBasePath = [documentsDir stringByAppendingPathComponent:datBaseName]; 

    [self checkAndCreateDatBase]; 
    [self readFilFromDatBase]; 

    if ([sb.text length] > 0) { 

     [self readAvancFromDatBase]; 
    } 

    [self readProdFromDatBase]; 
} 

- (void)checkAndCreateDatBase { 

    BOOL success; 

    NSFileManager *fileManager = [NSFileManager defaultManager]; 

    success = [fileManager fileExistsAtPath:datBasePath]; 

    if(success) { 

     return; 
    } 

    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:datBaseName]; 

    [fileManager copyItemAtPath:databasePathFromApp toPath:datBasePath error:nil]; 

    [fileManager release]; 
} 

- (void)readFilFromDatBase { 

    sqlite3 *datBase; 

    if(sqlite3_open([datBasePath UTF8String], &datBase) == SQLITE_OK) { 

     const char *sqlStat = "SELECT OPCAO FROM FILTRO WHERE R_E_C_N_O_ = 2"; 
     sqlite3_stmt *compiledStat; 

     if(sqlite3_prepare_v2(datBase, sqlStat, -1, &compiledStat, NULL) == SQLITE_OK) { 

      while(sqlite3_step(compiledStat) == SQLITE_ROW) { 

       opcFil = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStat, 0)]; 
      } 
     } 

     sqlite3_finalize(compiledStat); 
    } 

    sqlite3_close(datBase); 
} 

- (void)readAvancFromDatBase { 

    sqlite3 *datBase; 

    abrev = [[NSMutableArray alloc] init]; 

    if(sqlite3_open([datBasePath UTF8String], &datBase) == SQLITE_OK) { 

     const char *sqlStat; 
     sqlite3_stmt *compiledStat; 

     NSString *string1; 
     NSString *string2; 

     string1 = @"SELECT ABV_COMPLETA FROM ABREV WHERE ABV_REDUZ LIKE '%"; 
     string2 = @"%'"; 

     NSString *result = [NSString stringWithFormat:@"%@%@%@", string1, sb.text, string2]; 

     sqlStat = [result UTF8String]; 

     if(sqlite3_prepare_v2(datBase, sqlStat, -1, &compiledStat, NULL) == SQLITE_OK) { 

      while(sqlite3_step(compiledStat) == SQLITE_ROW) { 

       NSString *abvCompl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStat, 0)]; 

       iMAPArrayAbreviatura *arrayAbrev = [[iMAPArrayAbreviatura alloc] reduz:nil completa:abvCompl observacao:nil abrUnq:nil recno:nil]; 

       [abrev addObject:arrayAbrev]; 

       [arrayAbrev release]; 
      } 
     } 

     sqlite3_finalize(compiledStat); 
    } 

    sqlite3_close(datBase); 
} 

- (void)readProdFromDatBase { 

    sqlite3 *datBase; 

    iMAP = [[NSMutableArray alloc] init]; 

    if(sqlite3_open([datBasePath UTF8String], &datBase) == SQLITE_OK) { 

     sqlite3_stmt *compiledStat; 
     const char *sqlStat; 

     if ([sb.text length] == 0) { 

      sqlStat = "SELECT COD, ARTRF2, DESCRI FROM APSB1010"; 
     } 
     else { 

      NSString *string1; 
      NSString *string2 = @"%'"; 
      NSString *result; 

      if ([opcFil isEqualToString:@"1"]) { 

       string1 = @"SELECT COD, ARTRF2, DESCRI FROM APSB1010 WHERE TRIM(COD) LIKE '%"; 

       result = [NSString stringWithFormat:@"%@%@%@", string1, sb.text, string2]; 
      } 
      else if ([opcFil isEqualToString:@"2"]) { 

       string1 = @"SELECT COD, ARTRF2, DESCRI FROM APSB1010 WHERE TRIM(ARTRF2) LIKE '%"; 

       result = [NSString stringWithFormat:@"%@%@%@", string1, sb.text, string2]; 
      } 
      else if ([opcFil isEqualToString:@"3"]) { 

       string1 = @"SELECT COD, ARTRF2, DESCRI FROM APSB1010 WHERE TRIM(DESCRI) LIKE '%"; 

       result = [NSString stringWithFormat:@"%@%@%@", string1, sb.text, string2]; 
      } 
      else if ([opcFil isEqualToString:@"4"]) { 

       string1 = @"SELECT COD, ARTRF2, DESCRI FROM APSB1010 WHERE TRIM(APLICA) LIKE '%"; 

       result = [NSString stringWithFormat:@"%@%@%@", string1, sb.text, string2]; 
      } 
      else { 

       string1 = @"SELECT COD, ARTRF2, DESCRI FROM APSB1010 WHERE ("; 
       NSString *string1 = @"SELECT * FROM APSB1010 WHERE ("; 
       NSString *string3 = @"TRIM(DESCRI) LIKE '%"; 
       NSString *string4 = @" OR "; 
       NSString *string5 = @")"; 
       cons = [[NSString alloc] init]; 

       for (int i = 0; i < [abrev count]; i++) { 

        iMAPArrayAbreviatura *arrayAbrev = (iMAPArrayAbreviatura *)[abrev objectAtIndex:i]; 

        if (i > 0) { 

         cons = [cons stringByAppendingString:string4]; 
        } 

        cons = [cons stringByAppendingString:string3]; 
        cons = [cons stringByAppendingString:arrayAbrev.completa]; 
        cons = [cons stringByAppendingString:string2]; 
       } 

       result = [NSString stringWithFormat:@"%@%@%@", string1, cons, string5]; 
      } 

      sqlStat = [result UTF8String]; 
     } 

     if(sqlite3_prepare_v2(datBase, sqlStat, -1, &compiledStat, NULL) == SQLITE_OK) { 

      while(sqlite3_step(compiledStat) == SQLITE_ROW) { 

       NSString *prodCod = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStat, 0)]; 
       NSString *prodDescri = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStat, 2)]; 
       NSString *prodArtrf2 = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStat, 1)]; 

       iMAPArrayProdutos *arrayProd = [[iMAPArrayProdutos alloc] cod:prodCod prv1:nil grupo:nil picment:nil descri:prodDescri artrf2:prodArtrf2 um:nil embAp:nil desMax:nil imgAp:nil aplica:nil qAtu_01:nil qAtu_11:nil qAtu_12:nil qAtu_13:nil qAtu_14:nil prProm:nil recno:nil]; 

       [iMAP addObject: arrayProd]; 

       [arrayProd release]; 
      } 
     } 

     sqlite3_finalize(compiledStat); 
    } 

    sqlite3_close(datBase); 

    [tv reloadData]; 
} 

+ (NSString*)defaultValue { 

    return dadosProdutos; 
} 

+ (void)setDefaultValue:(NSString*)newDefaultValue { 

    if(dadosProdutos != newDefaultValue) { 

     [dadosProdutos release]; 

     dadosProdutos = [newDefaultValue retain]; 
    } 
} 

@end 

有人告訴我我做錯了什麼,我對這個問題越來越瘋狂。

+3

[示例代碼](http://sscce.org/)應該是完整且簡潔的 - 足以重新創建問題,但不能更多。發佈的示例有太多無關的代碼。 – outis 2011-12-26 11:34:34

+0

什麼是錯誤代碼? – Max 2011-12-26 11:35:12

+0

我希望有人會在這裏發現並解決這個bug。但是,如果您可以添加儘可能多的信息來簡化他們的任務,那將會很好。我想,你可以突出你懷疑這個錯誤的代碼。 – Kris 2011-12-26 11:36:13

回答

2

你有一堆的,你做的東西一樣

datBaseName = @"iMAP.sqlite"; 

的地方,我認爲datBaseName被定義爲保留的性質,但這這裏只是設置實例變量,而不調用訪問,所以當你打電話

[datBaseName release] 

你試圖釋放一個常量字符串 - 壞事會發生。相反,你應該做的

self.datBaseName = @"iMAP.sqlite"; 

你還做這樣

datBasePath = [documentsDir stringByAppendingPathComponent:datBaseName]; 

的東西再次,這是沒有要求的存取,所以datBasePath不被保留,並可能已被釋放由當你嘗試和使用它。

可能還有其他問題 - 嘗試將問題簡化爲問題更容易發現的更簡單示例。同時看看ARC這需要一些苦差事內存管理。 Xcode還有一些工具,例如NSZombies用於追蹤這樣的問題。