Ошибка выделения / освобождения Objective C

У меня есть следующая проблема:

в заголовке;

GDataXMLDocument *doc; NSString *xmlBody; @property (nonatomic,copy) NSString *xmlBody; @property (nonatomic,retain) GDataXMLDocument *doc; 

в м

 #import "tchLoader.h" #import "Variable.h" #import "DisplayVariable.h" @implementation tchLoader @synthesize responseXMLData,lastLoadedResponseXMLData; @synthesize conn; @synthesize doc; @synthesize xmlBody; - (void)loadXML:(id<tchLoaderDelegate>)delegate { NSString *theBaseXML= @"some xml code here" if (self.xmlBody==nil){ self.xmlBody=theBaseXML; } _delegate = delegate; /* SCNetworkReachabilityFlags flags; SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [@"www.alues.com" UTF8String]); SCNetworkReachabilityGetFlags(reachability, &flags); // The reachability flags are a bitwise set of flags that contain the information about // connection availability BOOL reachable = ! (flags & kSCNetworkReachabilityFlagsConnectionRequired); */ NSString *soapMessage =self.xmlBody; NSURL *url = [NSURL URLWithString:@"https://area.tch-values.com/soapmwp/mws"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]]; [request addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [request addValue: @"http://www.tch-values.com/webservice" forHTTPHeaderField:@"SOAPAction"]; [request addValue: msgLength forHTTPHeaderField:@"Content-Length"]; [request setHTTPMethod:@"POST"]; [request setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]]; if ([NSURLConnection canHandleRequest:request] && true) { self.conn = [[NSURLConnection alloc ]initWithRequest:request delegate:self]; if (self.conn) { self.responseXMLData = [NSMutableData data]; } } } -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"ERROR with theConenction"); [self.doc release]; [self.conn release]; [self.responseXMLData release]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"DONE. Received Bytes: %d", [self.responseXMLData length]); //[self.conn release]; if ([_delegate respondsToSelector:@selector(xmlDidFinishLoading)]) { [_delegate xmlDidFinishLoading]; } } -(void)insertAnswers: (NSMutableArray*) answeredVariables{ for (Variable * variable in answeredVariables) { NSInteger pageID=[variable pageId]; //NSMutableArray *answers=[NSMutableArray arrayWithCapacity:[[variable variableValues] count]]; NSString *path = [NSString stringWithFormat:@"//inferenceresponse/state/variable[pageId=%d]/valuedefinition",pageID]; NSArray *valueElement = [doc nodesForXPath:path error:nil]; GDataXMLElement *valueDefinitionElement; if (valueElement.count > 0) { valueDefinitionElement= (GDataXMLElement *) [valueElement objectAtIndex:0]; } GDataXMLElement * sourceElement = [GDataXMLNode elementWithName:@"source"]; [sourceElement addAttribute:[GDataXMLNode attributeWithName:@"type" stringValue:@"ask user"]]; GDataXMLElement * timeStampElement = [GDataXMLNode elementWithName:@"timestamp" stringValue:@"12345"]; [sourceElement addChild:timeStampElement]; GDataXMLElement * assignmentElement = [GDataXMLNode elementWithName:@"assignmentnumber" stringValue:@"6"]; for(NSString *answer in variable.variableValues){ GDataXMLElement * variableValueElement = [GDataXMLNode elementWithName:@"variablevalue"]; [variableValueElement addAttribute:[GDataXMLNode attributeWithName:@"value" stringValue:answer]]; [valueDefinitionElement addChild:variableValueElement]; } [valueDefinitionElement addChild:sourceElement]; [valueDefinitionElement addChild:assignmentElement]; } NSData *xmlData = self.doc.XMLData; NSString *theXML = [[NSString alloc] initWithBytes:[xmlData bytes] length:[xmlData length] encoding:NSUTF8StringEncoding]; theXML =[theXML stringByReplacingOccurrencesOfString:@"inferenceresponse" withString:@"inferencerequest"]; theXML =[theXML stringByReplacingOccurrencesOfString:@"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">" withString:@"<SOAP-ENV:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"> "]; theXML =[theXML stringByReplacingOccurrencesOfString:@"xmlns=\"\"" withString:@"xmlns=\"http://www.tch-values.com/xml/webservice\""]; theXML =[theXML stringByReplacingOccurrencesOfString:@"<state goalreached=\"false\">" withString:@"<state goalreached=\"false\"> <value>PlanKB</value> <goalvariable>myGoal</goalvariable> "]; self.xmlBody=theXML; [theXML release]; //[self.doc release]; NSLog(self.xmlBody); } - (NSMutableArray*)variablesForPageID:(NSString*)pageID { NSMutableArray *variables = nil; if (self.responseXMLData) { variables = [NSMutableArray arrayWithCapacity:10]; NSData *xmlData = self.responseXMLData; NSError *error; self.doc=nil; doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error]; if (self.doc == nil) { return nil; } NSArray *status = [doc nodesForXPath:@"//inferenceresponse/state[@goalreached='true']" error:nil]; if([status count]==1){ self.xmlBody=nil; Variable *variable=[[Variable alloc] init]; NSString *path = [NSString stringWithFormat:@"//inferenceresponse/state/displayvariables/display[@isDisplayShown='false']"]; NSArray *displayVariablesElements = [doc nodesForXPath:path error:nil]; NSMutableArray *disps=[[NSMutableArray alloc] init]; if(displayVariablesElements.count >0){ for(GDataXMLElement *disElement in displayVariablesElements){ DisplayVariable *disVar=[[DisplayVariable alloc] init]; NSArray *disPageid = [disElement nodesForXPath:@"@displayPageId" error:nil]; GDataXMLElement *Pageid = (GDataXMLElement *) [disPageid objectAtIndex:0]; disVar.displayPageId =Pageid.stringValue; NSArray *disName = [disElement nodesForXPath:@"displayname" error:nil]; if(disName.count >0){ GDataXMLElement *disNam = (GDataXMLElement *) [disName objectAtIndex:0]; disVar.displayName =disNam.stringValue; } NSArray *disValue = [disElement nodesForXPath:@"displayvalue" error:nil]; if(disValue.count >0){ GDataXMLElement *disVal = (GDataXMLElement *) [disValue objectAtIndex:0]; disVar.displayValue =disVal.stringValue; } NSArray *disId = [disElement nodesForXPath:@"@id" error:nil]; GDataXMLElement *disIdEl = (GDataXMLElement *) [disId objectAtIndex:0]; disVar.pageId =[disIdEl.stringValue intValue]; [disps addObject:disVar]; [disVar release]; } variable.displayVariables=disps; [disps release]; } variable.lastVariableofConsultation=YES; [variables addObject:variable]; [variable release]; } else{ NSArray *inferenceMembers = [doc nodesForXPath:@"//inferenceresponse/state/variable[not(valuedefinition/variablevalue)]" error:nil]; for (GDataXMLElement *variableElement in inferenceMembers) { Variable *variable=[[Variable alloc] init]; NSArray *items = [variableElement nodesForXPath:@"domaindefinition/domain/enumType/domainitem" error:nil]; NSMutableArray *domainItems = [NSMutableArray arrayWithCapacity:items.count]; for (int i=0; i<items.count;i++) { GDataXMLElement *domainItem = (GDataXMLElement *) [items objectAtIndex:i]; [domainItems addObject:domainItem.stringValue]; } variable.domainItems=domainItems; NSArray *names = [variableElement nodesForXPath:@"name/@name" error:nil]; if (names.count > 0) { GDataXMLElement *nameElement = (GDataXMLElement *) [names objectAtIndex:0]; variable.variableName = nameElement.stringValue; } NSArray *pageId = [variableElement nodesForXPath:@"pageId" error:nil]; } } return variables; } - (void)dealloc { [responseXMLData release] ; [lastLoadedResponseXMLData release] ; [conn release]; [doc release]; [xmlBody release]; [super dealloc]; } @end #import "tchLoader.h" #import "Variable.h" #import "DisplayVariable.h" @implementation tchLoader @synthesize responseXMLData,lastLoadedResponseXMLData; @synthesize conn; @synthesize doc; @synthesize xmlBody; 

Если я [релизXML] сработает, если я не выпущу XML, тогда он работает отлично, но я вижу утечку памяти в инструменте инструментов Simulator. (Есть также много утечек памяти, которые я вижу в этом коде, но не смог выяснить, что происходит с помощью инструмента instrumnets)

Это выглядит неправильно:

 [doc release]; 

Почему вы освобождаете объект, управляемый свойством?

В ваших операторах @synthesize их изменить:

 @synthesize doc = doc_; @synthesize xmlBody = xmlBody_; 

Затем исправьте все полученные ошибки, чтобы пройти через свойство, освободив свойства ТОЛЬКО в dealloc.

Редактировать:

Вы говорите, что он выдает освобождение XML. Этот код неверен:

 NSString *theXML = [[NSString alloc] initWithBytes:[xmlData bytes] length:[xmlData length] encoding:NSUTF8StringEncoding];     theXML =[theXML stringByReplacingOccurrencesOfString:@"inferenceresponse" withString:@"inferencerequest"]; [theXML release]; 

Вы выделяете строку, заменяете эту переменную вызовом «stringByReplacing …» с строкой, которая автореализована, а затем попытайтесь освободить результирующую строку, которая будет автореализоваться, что приведет к сбою. Когда вам не нужно поддерживать строку вокруг метода, в котором вы находитесь, ВСЕГДА используйте autorelease. Правильный код:

  NSString *theXML = [[[NSString alloc] initWithBytes:[xmlData bytes] length:[xmlData length] encoding:NSUTF8StringEncoding] autorelease];     theXML =[theXML stringByReplacingOccurrencesOfString:@"inferenceresponse" withString:@"inferencerequest"]; 

И выньте [релизXML] – утечки не будет.

Я думаю, что вы действительно должны переключиться на использование ARC, как только сможете … это избавит вас от множества таких недоразумений.

Если вы хотите выпустить ivar / свойство (сохранить), это не так:

 [self.doc release]; 

вместо:

 self.doc = nil; 

Одна «проблема» с одноэлементными объектами заключается в том, что они, по-видимому, протекают. Если вы создаете объект и никогда его не уничтожаете, значит, это говорит о том, что это утечка, даже если ваше намерение никогда не было выпущено.

 NSData *xmlData = doc.XMLData; newXML = [[NSString alloc] initWithBytes:[xmlData bytes] length:[xmlData length] encoding:NSUTF8StringEncoding]; 

Что нового в XML? это ивар и синтезировать его и сохранить? если да, то компилятор будет автоматически генерировать методы получения и установки.

 NSData *xmlData = doc.XMLData; self.newXML = [[NSString alloc] initWithBytes:[xmlData bytes] length:[xmlData length] encoding:NSUTF8StringEncoding]; self.timestamp = nil; 

Если это не свойство, то

 NSString* newXML = [[NSString alloc] initWithBytes:[xmlData bytes] length:[xmlData length] encoding:NSUTF8StringEncoding]; self.xmlBody=newXML; [newXML release]; 
Давайте будем гением компьютера.