[CFDictionary发布]:消息发送到解除分配的实例,有什么问题?

时间:2012-03-13 14:13:50

标签: objective-c ios memory nszombie

我一直收到这个表示僵尸的错误。 我把它缩小到这两种方法,但我不能为我的生活弄清楚什么是错的。

有什么想法吗?

-(void) getWeatherDetail: (NSString *)query
{
    @try 
    {
        NSString *urlString111 = [NSString stringWithFormat:@"http://www.google.com/ig/api?weather=%@",query];
        urlString111 = [urlString111 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSURL *url = [NSURL URLWithString:urlString111];

        NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];

        NSData *returnData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil];

        if(xmlParser)
        {
            xmlParser=nil;
            [xmlParser release];

        }   


        xmlParser = [[NSXMLParser alloc] initWithData: returnData];
        isForeCast = NO;
        isFirstForeCastEnd = NO;
        if (!self.arrForecastAll) {
            self.arrForecastAll = [[NSMutableArray alloc] init];
        }
        [self.arrForecastAll removeAllObjects];
        [xmlParser setDelegate: self];
        [xmlParser setShouldResolveExternalEntities: YES];
        [xmlParser parse];

//        self.logString = [NSString stringWithFormat:@"%@Date & Time: %@ | Text: Getting Weather detail.\n", self.logString, [NSDate date]];
//        [self updateLogFile:self.logString];
    }
    @catch (NSException *exception) {
        NSLog(@"Ad exc %@",[exception description]);
    }
    @finally {

    }
}

这一个..

-(void)getCurrentCityName
{
    //////Method to find current city name
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    @try
    {
        if ([self.arrSettings count] > 0 && [[[self.arrSettings objectAtIndex:3] objectForKey:@"Value"] isEqualToString:@"Current Location"]) 
        {
            if (currentlat != 0 && currentlong != 0) {
                NSURL *urlString;




                NSLog(@"lat %f %f" ,currentlat,currentlong);
                urlString =[NSURL URLWithString:[NSString stringWithFormat:@"http://maps.google.com/maps/geo?output=json&oe=utf-8&ll=%f,%f&key=[removed API key]",currentlat,currentlong]];



                NSLog(@"\n\n-------------------------TF-Get City Name -Request-----------------------------\n%@\n\n",urlString);
                NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ; 

                [request setURL:urlString];
                NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse:nil error: nil ]; 
                NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

                NSLog(@"\n\n------------------------TF-Get City Name -Response------------------------\n\n%@\n\n",returnString);


                [request release];
                NSDictionary *dictAddress=[returnString objectFromJSONString];
                NSLog(@"dictAddress  %@",[dictAddress description]);

                [returnString release];

                NSString *strCity = [NSString stringWithFormat:@"Getting Location"];
                NSLog(@"strCity %@",strCity);
                if ([[dictAddress allKeys] count] > 1)
                {

                    if ([[[[[[dictAddress valueForKey:@"Placemark"] objectAtIndex:0] valueForKey:@"AddressDetails"] valueForKey:@"Country"] valueForKey:@"AdministrativeArea"] valueForKey:@"SubAdministrativeArea"])
                    {
                        strCity = [NSString stringWithFormat:@"%@,%@",
                                   [[[[[[[[dictAddress valueForKey:@"Placemark"] objectAtIndex:0] valueForKey:@"AddressDetails"] valueForKey:@"Country"] valueForKey:@"AdministrativeArea"] valueForKey:@"SubAdministrativeArea"] valueForKey:@"Locality"] valueForKey:@"LocalityName"],
                                   [[[[[[dictAddress valueForKey:@"Placemark"] objectAtIndex:0] valueForKey:@"AddressDetails"] valueForKey:@"Country"] valueForKey:@"AdministrativeArea"] valueForKey:@"AdministrativeAreaName"]];
                    }
                    else {
                        strCity = [NSString stringWithFormat:@"%@,%@",
                                   [[[[[[[dictAddress valueForKey:@"Placemark"] objectAtIndex:0] valueForKey:@"AddressDetails"] valueForKey:@"Country"] valueForKey:@"AdministrativeArea"] valueForKey:@"Locality"] valueForKey:@"LocalityName"],
                                   [[[[[[dictAddress valueForKey:@"Placemark"] objectAtIndex:0] valueForKey:@"AddressDetails"] valueForKey:@"Country"] valueForKey:@"AdministrativeArea"] valueForKey:@"AdministrativeAreaName"]];
                    }

                    self.strCurrentCity = strCity;
                    [self getWeatherDetail:self.strCurrentCity];
                }

            }
            else 
            {
                self.strCurrentCity = @"Current Location";
            }

        }
        else
        {
            self.strCurrentCity = [[self.arrSettings objectAtIndex:3] objectForKey:@"Value"];
            [self getWeatherDetail:self.strCurrentCity];
        }

//        self.logString = [NSString stringWithFormat:@"%@Date & Time: %@ | Text: Getting current city name. CityName: %@\n", self.logString, [NSDate date], self.strCurrentCity];
//        [self updateLogFile:self.logString];


        [pool release];
    }
    @catch (NSException *exception) {
        NSLog(@"Ad exc %@",[exception description]);
    }
    @finally {

    }
}

1 个答案:

答案 0 :(得分:2)

这是您通过直接ivar访问获得的典型内存管理问题。使用访问器来处理你的ivars,你的代码会更简单,你就不会有这些错误。

所以替换这段代码:

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

    xmlParser = [[NSXMLParser alloc] initWithData: returnData];
    isForeCast = NO;
    isFirstForeCastEnd = NO;
    if (!self.arrForecastAll) {
        self.arrForecastAll = [[NSMutableArray alloc] init];
    }

使用:

    self.xmlParser = [[[NSXMLParser alloc] initWithData: returnData] autorelease];
    self.isForeCast = NO;
    self.isFirstCoreCastEnd = NO;
    if (!self.arrForecastAll) {
        self.arrForecastAll = [NSMutableArray array];
    }

这也可以消除您对arrForecastAll的分配中的泄漏。

关于你的第二个块,每当你release变量时,如果变量没有立即超出范围,你应该总是将它设置为nil。例如,您[request release]后面应跟request = nil

顺便说一下,为什么要把所有这些都放在@try块中呢? ObjC中的异常处理是罕见的,昂贵的,并且泄漏内存。例外通常表示ObjC中存在不可恢复的错误,并且不是一般的错误处理系统。有时候@try是合适的,但我在这里看不到任何理由。