我的应用程序中存在内存分配问题。这导致冻结,最终导致程序结束。回顾一下我的代码,我意识到大部分内存分配都在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
有人告诉我我做错了什么,我对这个问题感到疯狂。
答案 0 :(得分:2)
你有很多地方可以做像
这样的事情datBaseName = @"iMAP.sqlite";
我假设datBaseName
被定义为保留属性,但这里只设置实例变量而不调用访问器,所以当你调用时
[datBaseName release]
你试图释放一个常量字符串 - 会发生坏事。相反,你应该做
self.datBaseName = @"iMAP.sqlite";
你也在做这样的事情
datBasePath = [documentsDir stringByAppendingPathComponent:datBaseName];
这再次没有调用访问者,因此datBasePath
未被保留,并且可能在您尝试使用它时已被释放。
可能还有其他问题 - 尝试将问题减少到一个更容易发现问题的最小例子。另请查看ARC,其中包含了一些内存管理方面的苦差事。 Xcode还有一些工具,例如NSZombies
,用于跟踪此类问题。