我有以下问题:
标题中的;
GDataXMLDocument *doc;
NSString *xmlBody;
@property (nonatomic,copy) NSString *xmlBody;
@property (nonatomic,retain) GDataXMLDocument *doc;
in m
#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;
如果我[theXML发布]它崩溃,如果我不发布XML,那么它工作完美,但我看到模拟器工具中的内存泄漏。 (我在这段代码中看到了很多内存泄漏,但无法通过instrumnets工具弄清楚发生了什么)
答案 0 :(得分:1)
这看起来不对:
[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 ...”调用用自动释放的字符串替换该变量,然后尝试释放自动释放的结果字符串,该字符串将崩溃。如果您不需要在所使用的方法之后保留字符串,请始终使用自动释放。正确的代码是:
NSString *theXML = [[[NSString alloc] initWithBytes:[xmlData bytes] length:[xmlData length] encoding:NSUTF8StringEncoding] autorelease];
theXML =[theXML stringByReplacingOccurrencesOfString:@"inferenceresponse" withString:@"inferencerequest"];
取出[theXML release] - 不会泄漏。
我认为你应该尽快切换到使用ARC ......这样可以避免许多这样的误解。
答案 1 :(得分:1)
如果你想发布一个ivar / property(保留),这不是它的方法:
[self.doc release];
代替:
self.doc = nil;
答案 2 :(得分:0)
单例对象的一个“问题”是它们似乎泄漏。如果您创建一个对象并且永远不会销毁它,那么即使您的意图永远不会释放它,仪器也会说它是泄漏的。
答案 3 :(得分:0)
NSData *xmlData = doc.XMLData;
newXML = [[NSString alloc] initWithBytes:[xmlData bytes] length:[xmlData length]
encoding:NSUTF8StringEncoding];
你的newXML是什么?它是一个ivar并合成它并保留它?如果是,编译器将自动生成getter和setter方法。
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];