iPhone SDK中NSMutableArray、NSArray、NSString内存泄漏
在我的应用程序中,我在NSMutableArray、NSArray和NSString中发现内存泄漏 这是代码iPhone SDK中NSMutableArray、NSArray、NSString内存泄漏,iphone,objective-c,ios4,memory-leaks,iphone-sdk-3.0,Iphone,Objective C,Ios4,Memory Leaks,Iphone Sdk 3.0,在我的应用程序中,我在NSMutableArray、NSArray和NSString中发现内存泄漏 这是代码 NSString *subQuery = [NSString stringWithFormat:@"SELECT %@ FROM tbl_lang WHERE glossary = '%@'",append1,glossaryName]; NSArray *subArray1 = [[[self returnExecuteQuery:subQuery] mutableCo
NSString *subQuery = [NSString stringWithFormat:@"SELECT %@ FROM tbl_lang WHERE glossary = '%@'",append1,glossaryName];
NSArray *subArray1 = [[[self returnExecuteQuery:subQuery] mutableCopy] autorelease];
[subArray addObjectsFromArray:subArray1];
NSString *columnQuery = [NSString stringWithFormat:@"select AutoID,%@ from tbl_lang where glossary='%@'",lblshortName.text,glossaryName];
NSArray *newArray =[[[self returnExecuteQuery:columnQuery] mutableCopy] autorelease];
[langArray addObjectsFromArray:newArray];
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
for (int i=0; i<[newArray count]; i++) {
NSString *cellText = [[newArray objectAtIndex:i] valueForKey:[NSString stringWithFormat:@"%@",lblshortName.text]];
if (cellText != (NSString *)[NSNull null] && ![cellText isEqualToString:@""] ) {
NSString *decodedString3 = [NSString stringWithUTF8String:[cellText cStringUsingEncoding:[NSString defaultCStringEncoding]]];
[tempArray addObject:[NSString stringWithFormat:@"%@ : %@",lblshortName.text, decodedString3]];
}
else {
[tempArray addObject:@"<empty>"];
}
NSString *detail = @"_________________";
for (int j=0; j<[lableNameArray count]; j++) {
NSString *checkNull=[[subArray1 objectAtIndex:i] valueForKey:[NSString stringWithFormat:@"%@",[lableNameArray objectAtIndex:j]]];
if(checkNull != (NSString *)[NSNull null] && checkNull.length > 0)
{
NSString *decodedString4 = [NSString stringWithUTF8String:[checkNull cStringUsingEncoding:[NSString defaultCStringEncoding]]];
detail = [NSString stringWithFormat:@"%@\n%@ : %@ ",detail,[lableNameArray objectAtIndex:j],decodedString4];
}
}
[detailTextArray addObject:detail];
}
NSString*子查询=[NSString stringWithFormat:@“从tbl_lang中选择%@其中词汇表='%@',附录1,词汇表名称];
NSArray*子数组1=[[self-returnExecuteQuery:subQuery]可变表复制]自动释放];
[子阵列添加对象阵列:子阵列1];
NSString*columnQuery=[NSString stringWithFormat:@“选择自动ID,%@自tbl_lang,其中术语表='%@',lblshortName.text,glossaryName];
NSArray*newArray=[[self-returnExecuteQuery:columnQuery]mutableCopy]autorelease];
[langArray addObjectsFromArray:newArray];
NSMutableArray*tempArray=[[NSMutableArray alloc]init];
对于(int i=0;i不确定是什么导致内存泄漏,但这可能会有所帮助。这是一种更直接的复制阵列的方法,可以避免泄漏:
NSArray *langArray =[[NSArray alloc] initWithArray: [self returnExecuteQuery:columnQuery] copyItems: YES];
这基本上是对returnExecuteQuery返回的数组进行一级深度复制
我不确定mutableCopy是如何工作的,这可能与泄漏有关。如果它复制旧数组中的对象并将其添加到新数组中,则它们可能会以保留计数2(1来自副本,1来自被添加到数组中)进入数组这样做没有多大意义。但是,如果这样做的话,这可能是泄漏的原因。您可以在完成tempArray之后(在循环之后)释放它
通常,较高级别的泄漏隐藏在较低级别的泄漏中(即容器泄漏导致其所有内容也泄漏),这可能是字符串的情况
使用mutableCopy]autorelease];
对了。Olease试试这一个,在上面的代码中,您创建了两个属于autorelease池的多个对象。这是一个版本,我试图处理这些字符串变量的释放
其次,细节
的泄漏是因为您在代码中多次取消引用它。对于子阵列1
,请参阅注释
NSMutableString *subQuery =[ [NSMutableString alloc] initWithFormat:@"SELECT %@ FROM tbl_lang WHERE glossary = '%@'",append1,glossaryName];
// please make returnExecuteQuery's returned array autorelease if it is not.
NSArray *subArray1 = [[self returnExecuteQuery:subQuery] mutableCopy] ;
[subArray addObjectsFromArray:subArray1];
[subQuery release];
NSMutableString *columnQuery ==[ [NSMutableString alloc] initWithFormat:@"select AutoID,%@ from tbl_lang where glossary='%@'",lblshortName.text,glossaryName];
NSArray *newArray =[[self returnExecuteQuery:columnQuery] mutableCopy] ;
[langArray addObjectsFromArray:newArray];
[columnQuery relese];
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
for (int i=0; i<[newArray count]; i++) {
NSMutableString *tempKey = [[NSMutableString alloc]initWithFormat:@"%@",lblshortName.text]];
NSString *cellText = [[newArray objectAtIndex:i] valueForKey:tempKey];
[tempKey release];
if (cellText != (NSString *)[NSNull null] && ![cellText isEqualToString:@""] ) {
NSString *decodedString3 = [NSString stringWithUTF8String:[cellText cStringUsingEncoding:[NSString defaultCStringEncoding]]];
NSMutableString *tempString = [[NSMutableString alloc] initWithFormat:@"%@ : %@",lblshortName.text, decodedString3]];
[tempArray addObject:tempString];
[tempString release];
}
else {
[tempArray addObject:@"<empty>"];
}
NSMutableString *detail = nil;
for (int j=0; j<[lableNameArray count]; j++)
{
detail = [[ NSMutableString alloc]initWithString:@"_________________"];
NSMutableString *key = [[NSMutableString alloc]initWithFormat:@"%@",[lableNameArray objectAtIndex:j]];
NSString *checkNull=[[subArray1 objectAtIndex:i] valueForKey:key];
[key release];
if(checkNull != (NSString *)[NSNull null] && checkNull.length > 0)
{
NSString *decodedString4 = [NSString stringWithUTF8String:[checkNull cStringUsingEncoding:[NSString defaultCStringEncoding]]];
[detail setString:[NSString stringWithFormat:@"%@\n%@ : %@ ",detail,[lableNameArray objectAtIndex:j],decodedString4]];
}
[detailTextArray addObject:detail];
[detail release];
}
}
[subArray1 release];
[newArray release];
更新2:
if(checkNull != (NSString *)[NSNull null] && checkNull.length > 0)
{
NSString *decodedString4 = [NSString stringWithUTF8String:[checkNull cStringUsingEncoding:[NSString defaultCStringEncoding]]];
[detail appendFormat:@"%@\n%@ : %@ ",detail,[lableNameArray objectAtIndex:j],decodedString4]];
}
谢谢,什么是-returnExecuteQuery:
做什么?它返回一个拥有的还是非拥有的对象?它的契约是否说明了多个调用之间返回值的有效性?是否释放tempArray?在哪里?此外,尝试释放subray1和newArray(而不是自动释放它们)在addObjectsFromArray之后。@Fran:我试图在main for loop之后释放两个数组,但它给了我子数组和langArray的EXEC_BAD_访问错误。@BaVariable:returnExecuteQuery
给了我从数据库得到的NSArray。我得到了相同的警告…这是我的屏幕截图,..感谢代码,但仍然有一些问题,我想解决添加[detailTextArray addObject:detail];[detail release]
在for循环之后,它在细节中显示泄漏。Subray1和newArray仍然在仪器中显示泄漏。请查看上述代码,并回答代码中的注释,以便场景更加清晰。感谢第一和第二条注释:数组是自动释放的。第三条注释:我正在检查空值或空值的条件s、 如果checknull不为空或null,则应使用\n
附加详细字符串。这样我就可以在单元格的详细文本中显示它。@Meghan,我已经更新了详细字符串附加操作的代码。请确保您正确释放数组@salo.dm:谢谢您的答复。这在某些情况下对我有帮助。它仍然显示泄漏detail
、subray1
和newArray
。如果使用此代码,您将不需要newArray。您可以删除引用newArray的整行。类似地,您可以通过将代码中的第2行和第3行替换为以下内容来删除subray1:NSArray*subray=[[NSArray alloc]initWithArray:[self returnExecuteQuery:subQuery]copyItems:YES];dm:每次调用此方法时,它都会在langArray中添加新的数据量。因此这对我没有帮助
if(checkNull != (NSString *)[NSNull null] && checkNull.length > 0)
{
NSString *decodedString4 = [NSString stringWithUTF8String:[checkNull cStringUsingEncoding:[NSString defaultCStringEncoding]]];
[detail appendFormat:@"%@\n%@ : %@ ",detail,[lableNameArray objectAtIndex:j],decodedString4]];
}