仪器中有内存泄漏的类

问题描述:

我有几个类,其中的函数是针对WEB服务执行SQL语句以获取或设置数据库中的数据。仪器中有内存泄漏的类

工作正常,但问题是当我在仪器/泄漏测试中90%的泄漏是因为这些类。

你能告诉我我在丢什么吗?

谢谢。

下面是代码:

在数据存储:

.H

@interface iSQLResult : NSObject { 
    NSMutableArray *Records; 
} 
@property (nonatomic, assign) int CountX; 
@property (nonatomic, assign) int CountY; 
@property (nonatomic, retain) NSMutableArray *Columns; 
@property (nonatomic, retain) NSMutableArray *Records; 
@property (nonatomic, retain) NSMutableArray *FieldsNames; 
@property (nonatomic, assign) int ErrorCode; 
@property (nonatomic, retain) NSString *ErrorDescription; 


-(void)addField:(NSString*)fieldName; 
-(void)addRecord:(NSMutableArray*)items; 
-(NSMutableArray *)getRecord:(int)y; 
-(NSString*)getValue:(int) x posY:(int) y; 
-(NSString*)getValueByName:(NSString *) colName posY:(int) y; 
-(void)setValueByName:(NSString *) colName posY:(int) y value:(NSString *)value; 
-(id) copyWithZone: (NSZone *) zone; 
@end 

.M

#import "iSQLResult.h" 
#import <stdarg.h> 

@implementation iSQLResult 
@synthesize CountX; 
@synthesize CountY; 
@synthesize Columns; 
@synthesize Records; 
@synthesize FieldsNames; 
@synthesize ErrorCode; 
@synthesize ErrorDescription; 

-(id)init 
{ 
    self = [super init]; 

    if (self) 
    { 
     self.CountX =0; 
     self.CountY =0; 
     self.ErrorCode = 0; 
     self.ErrorDescription = @""; 

     self.FieldsNames = [NSMutableArray array]; 
     self.Columns = [NSMutableArray array]; 
     self.Records = [NSMutableArray array]; 

    } 

    return self; 
} 
-(void)removeRecord:(int)index 
{ 
    [self.Records removeObjectAtIndex:index]; 
    self.CountY = self.CountY - 1; 
} 
-(void)addField:(NSString*)fieldName 
{ 
    [self.FieldsNames addObject:[NSString stringWithFormat:@"%@", fieldName]]; 
    self.CountX = self.CountX +1; 
} 
-(void)addRecord:(NSMutableArray*)items 
{ 
    [self.Records addObject:items]; 
    self.CountY = self.CountY +1; 
} 
-(NSMutableArray *)getRecord:(int)y 
{ 
    return [Records objectAtIndex:y]; 
} 
-(NSString *)getValue:(int) x posY:(int)y 
{ 
    return [[NSString stringWithFormat:@"%@", [[Records objectAtIndex:y] objectAtIndex:x]] copy]; 
} 
-(NSString*)getValueByName:(NSString *) colName posY:(int) y 
{ 
    int a=0; 
    for (a=0;a<CountX;a++) 
    { 
     if ([[colName uppercaseString] isEqualToString:[[FieldsNames objectAtIndex:a] uppercaseString]]) 
     { 
      return [[NSString stringWithFormat:@"%@", [[Records objectAtIndex:y] objectAtIndex:a]] copy]; 
     } 
    } 
    return @""; 
} 
-(void)setValueByName:(NSString *) colName posY:(int) y value:(NSString *)value 
{ 
    int a=0; 
    for (a=0;a<CountX;a++) 
    { 
     if ([[colName uppercaseString] isEqualToString:[[FieldsNames objectAtIndex:a] uppercaseString]]) 
     { 
      [[Records objectAtIndex:y] replaceObjectAtIndex:a withObject:value]; 
     } 
    } 

} 
-(void)dealloc 
{ 
    [Columns release]; 
    [Records release]; 
    [FieldsNames release]; 
    [ErrorDescription release]; 

    [super dealloc]; 
} 
-(id) copyWithZone: (NSZone *) zone 
{ 
    iSQLResult *SQLRCopy = [[iSQLResult allocWithZone: zone] init]; 

    [SQLRCopy setCountX:self.CountX]; 
    [SQLRCopy setCountY:self.CountY]; 
    [SQLRCopy setRecords:[self.Records mutableCopyWithZone:zone]]; 
    [SQLRCopy setColumns:[self.Columns mutableCopyWithZone:zone]]; 
    [SQLRCopy setFieldsNames:[self.FieldsNames mutableCopyWithZone:zone]]; 
    [SQLRCopy setErrorCode:self.ErrorCode]; 
    [SQLRCopy setErrorDescription:[self.ErrorDescription copyWithZone:zone]]; 

    return SQLRCopy; 
} 
@end 

类谁索要数据到web服务通信类,并获得xml结构:

.H

#import <Foundation/Foundation.h> 
#import "iSQLResult.h" 
#import "IM2_WebServiceComm.h" 

@interface iSQL : NSObject <NSXMLParserDelegate> { 

    iSQLResult *SQLR; 
    IM2_WebServiceComm * WSC; 

    NSXMLParser *xmlParser; 
    BOOL Found; 
    BOOL FieldsReaded; 
    BOOL loadFieldsNow; 
    BOOL loadErrNumNow; 
    BOOL loadErrDesNow; 
    NSString *chunksString; 
    NSMutableArray *tempRecord; 
} 
@property (nonatomic, retain) NSString *URLConnection; 
-(void)SQLReader:(NSString*)SQLString; 
-(void)SQLExec:(NSString*)SQLString; 
-(void)setURLConnection:(NSString *) WebSURL; 
-(iSQLResult*) getSQLR; 
-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName; 
-(void) parser:(NSXMLParser *) parser foundCharacters:(NSString *)string; 
-(void) parser:(NSXMLParser *) parser didStartElement:(NSString *) elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *) qName attributes:(NSDictionary *) attributeDict; 
@end 

.M

#import "iSQL.h" 
@implementation iSQL 
@synthesize URLConnection; 
- (iSQLResult*)getSQLR 
{ 
    return [SQLR copy]; 
} 
-(void)SQLExec:(NSString*)SQLString 
{ 

    FieldsReaded = NO; 
    Found = NO; 
    loadFieldsNow = NO; 

    if (SQLR) 
    { 
     [SQLR release]; 
     SQLR = nil; 
    } 


SQLR = [[iSQLResult alloc] init]; 

WSC = [[IM2_WebServiceComm alloc] init]; 
[WSC setURL:URLConnection]; 

NSString *theXML = [WSC callMethod:@"ExecNonQuery" sendInstruction:SQLString]; 

@try 
{ 
    xmlParser = [[NSXMLParser alloc] initWithData:[theXML dataUsingEncoding:NSUTF8StringEncoding]]; 
    [xmlParser setDelegate: self]; 
    [xmlParser setShouldResolveExternalEntities:NO]; 
    if(![xmlParser parse]) 
    { 
     NSLog(@"ERROR PARSING"); 
    } 
    [xmlParser release]; 
} 
@catch(NSException * ex) 
{ 
    NSLog(@"%@",[[ex reason] UTF8String]); 
} 
[WSC release]; 
} 
-(void)SQLReader:(NSString*)SQLString 
{ 

FieldsReaded = NO; 
Found = NO; 
loadFieldsNow = NO; 

if (SQLR) 
{ 
    [SQLR release]; 
    SQLR = nil; 
} 

SQLR = [[iSQLResult alloc] init]; 

WSC = [[IM2_WebServiceComm alloc] init]; 
[WSC setURL:URLConnection]; 

NSString *theXML = [WSC callMethod:@"ExecSQL" sendInstruction:SQLString]; 

@try 
{ 
    xmlParser = [[NSXMLParser alloc] initWithData:[theXML dataUsingEncoding:NSUTF8StringEncoding]]; 
    [xmlParser setDelegate: self]; 
    [xmlParser setShouldResolveExternalEntities:NO]; 
    if(![xmlParser parse]) 
    { 
     NSLog(@"ERROR PARSING"); 
    } 
    [xmlParser release]; 
} 
@catch(NSException * ex) 
{ 
    NSLog([NSString stringWithFormat:@"%@",[[ex reason] UTF8String]]); 
} 
[WSC release]; 
} 

-(iSQLResult *)getSingleSQLR:(iSQLResult *)SQLSource usingRow:(int)y 
{ 

iSQLResult *SQLRAux = [[[iSQLResult alloc]init]retain]; 

[SQLRAux setCountX:SQLSource.CountX]; 
[SQLRAux addRecord:[SQLSource getRecord:y]]; 
[SQLRAux setFieldsNames:SQLSource.FieldsNames]; 

return SQLRAux; 

} 

-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{ 
    NSLog(@"Error on XML Parse: %@", [parseError localizedDescription]); 
} 

//#pragma XML Parser Delegate Methods 
-(void) parser:(NSXMLParser *) parser didStartElement:(NSString *) elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *) qName attributes:(NSDictionary *) attributeDict 
{ 
    if (!chunksString) 
{ 
    chunksString = [[NSString alloc] init]; 
} 
chunksString = @""; 
if ([elementName isEqualToString:@"ErrCode"]) 
{ 
    loadErrNumNow = YES; 
} 
if ([elementName isEqualToString:@"ErrDesc"]) 
{ 
    loadErrDesNow = YES; 
} 

if ([elementName isEqualToString:@"Table"]) 
{ 
    Found = YES; 
    loadFieldsNow = NO; 
    tempRecord = [[NSMutableArray alloc] init]; 
} 

if (Found && ![elementName isEqualToString:@"Table"]) 
{ 
    loadFieldsNow = YES; 
    if (!FieldsReaded) 
    { 
     [SQLR addField:elementName]; 
    } 
} 
} 

-(void) parser:(NSXMLParser *) parser foundCharacters:(NSString *)string 
{ 
    chunksString = [chunksString stringByAppendingString:string]; 
}  

-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
{ 
NSString * finalString; 
finalString = [NSString stringWithFormat:@"%@",chunksString]; 

if (loadErrNumNow) 
{ 
    [SQLR setErrorCode:[finalString intValue] ]; 
    loadErrNumNow = NO; 
} 
if (loadErrDesNow) 
{ 
    [SQLR setErrorDescription:finalString]; 
    loadErrDesNow = NO; 
}   

if (Found) 
{ 
    if (loadFieldsNow) 
    { 
     [tempRecord addObject:finalString]; 
    } 
} 

if ([elementName isEqualToString:@"Table"]) 
{ 
    [SQLR addRecord:tempRecord]; 
    [tempRecord release]; 
    Found = NO; 
    FieldsReaded = YES; 
    loadFieldsNow = NO; 

} 
} 

-(void)dealloc 
{ 
    if (SQLR) 
    { 
     [SQLR release]; 
     SQLR = nil; 
    } 

    [URLConnection release]; 

    [super dealloc]; 

} 
@end 

这绝对是一个越野车类,因为漏水,每次访问都是泄漏:(

任何帮助吗?

+1

Woa。这是大量的代码,要求在互联网上的随机无偿人员查找内存管理错误。如果您需要帮助,请将其缩小为小部分,并指定具体错误。 – Almo 2012-02-29 21:50:54

+0

你运行过分析仪吗? – 2012-02-29 21:53:38

+0

看起来你永远不会在SQLExec中释放分配给SQLR的第二个值。 (请学习标准C语言大写惯例,让您的代码更易于其他人使用。) – 2012-02-29 22:00:14

这里有一些事情我注意到:

- [iSQLResult copyWithZone:]

你发送mutableCopyWithZone的结果:(返回保留的对象)的制定者,它保留了再次对象。要解决这个问题的一种方式是自动释放的副本:

[SQLRCopy setRecords:[[self.Records mutableCopyWithZone:zone] autorelease]] 

- [Interactive SQL SQLEXEC:]和 - [Interactive SQL SQLReader的:]

实例变量WSC和xmlPareser被alloced然后释放,但没有设置为零。这不是泄漏,但是您保留对已发布对象的引用。如果你解除这一点,你会崩溃。

- [Interactive SQL getSingleSQLR:usingRow:]

iSQLResult *SQLRAux = [[[iSQLResult alloc]init]retain]; 

您的意思是自动释放,而不是保留在那里? (如果你没有,你不应该也自动释放在getSQLR回报,一致性?)

- [Interactive SQL解析器:didStartElement:的namespaceURI:qualifiedName中:属性:]

chunksString是alloced(+ 1保留),但后来在解析器:foundCharacters:你失去了引用(即泄漏字符串)并用自动释放字符串替换它。


这就是我注意到的一切。这听起来像你泄漏的不仅仅是这些对象,所以我猜你也在泄漏iSQL和/或iSQLResult对象。请记住,当你泄漏一个对象时,你也会泄漏这些对象持有的引用。即使这些类是无漏洞的,如果实例化这些类的代码没有正确地释放对象,您也会看到这些类中的所有成员都泄漏了。修复泄漏时,请务必首先查找“顶层”对象。

+0

感谢您的回应。这意味着每次我声明一个iSQLResult对象并将其分配给[iSQL getSQLR]的返回时,签名对象也必须被释放?谢谢。 – NemeSys 2012-03-01 09:25:21

+0

是的, - [iSQL getSQLR]中的复制方法返回带有+1保留计数的对象。为了避免泄漏,你需要释放当调用范围完成或更改代码返回[[SQLR copy] autorelease]。 – davehayden 2012-03-01 22:18:14