本文介绍了Objective C alloc / release错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下问题:

在标题中;

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工具弄清楚发生了什么)

If I [theXML release] it crashes, If I dont release theXML then it works perfect but I see memory leak in simulator Instruments tool. (There are also lots of memory leaks I see in this code but couldnt figure out by instrumnets tool what is going on)

推荐答案

这看起来不对:

[doc release];

为什么要发布由物业管理的对象?

Why are you releasing an object managed by a property?

在@synthesize语句中将它们更改为:

In your @synthesize statements change them to:

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

然后修复所有产生的错误以通过该属性,仅在dealloc中释放属性。

Then fix all the resulting errors to go through the property, releasing the properties ONLY in dealloc.

编辑:

你说它崩溃了释放XML。这段代码错了:

You say it crashes releasing theXML. This code is wrong:

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

你分配一个字符串,用stringByReplacing ...调用用一个字符串替换该变量是自动释放的,然后尝试释放自动释放的结果字符串,该字符串将崩溃。如果您不需要在所使用的方法后保留字符串,请始终使用自动释放。正确的代码是:

You alloc a string, replace that variable with the "stringByReplacing..." call with a string that is autoreleased, then try to release the resulting string that is autoreleased which will crash. When you don't need to keep a string around after the method you are in, ALWAYS use autorelease. The correct code is:

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

并取出[theXML release] - 不会泄漏。

And take out [theXML release] - there will be no leak.

我认为你应该尽快切换到使用ARC ......这样可以避免许多这样的误解。

I think you should really switch to using ARC as soon as you possibly can... it will save you from a lot of such misunderstandings.

这篇关于Objective C alloc / release错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 02:05