开发者

How to improve memory management when doing low level http work

I'm starting to cleanup an older prototype I worked on and it's doing a great deal of low level http work. The problem I'm having is how and when to do a release inside the "connectionDidFinishLoading" method below. I have some items only created inside the if but when I release them before the method call I get several BAD ACCESS errors and thought to ask how I should be doing memory management in this scenario.

- (void)searchForNewHats:(HatViewController *)hatVwController
{
  responseData = [[NSMutableData data] retain]; //responseData is a property that I retain - fyi
  hatController = hatVwController; //hatController is a property that I retain - fyi

  NSURL *url = [NSURL URLWithString:@"http://localhost/jsondata"];
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];

  [request setHTTPMethod:@"GET"];

  [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

- (void)conne开发者_开发问答ctionDidFinishLoading:(NSURLConnection *)connection {
    [connection release];

    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

    NSArray *json = [responseString JSONValue];

  if (json != NULL) {
    NSArray *items = [json valueForKeyPath:@"d"];

    HatParseJson* hatParseJson = [[HatParseJson alloc] init];
    NSArray* hatz = [hatParseJson parseJson:items];

    NSMutableArray* newHats = [[NSMutableArray alloc] init];
    NSUInteger i, count = [hatz count];
    for (i = 0; i < count; i++) {
      Hat* obj = [hatz objectAtIndex:i];
      [newHats addObject:obj];
      //[obj release]; this blows up for example ...
    }

    [hatParseJson release];

    [hatController newHatJsonFinished:newReleases];
  }else {
    [hatController newHatJsonFinished:nil];
  }

  [responseString release];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [responseData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
  [responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {

}

Thank you in advance


some updates and comments inline:

- (void)searchForNewHats:(HatViewController *)hatVwController
{
    assert(0 == responseData);
    responseData = [NSMutableData new];
    assert(0 == hatController);
    self.hatController = hatVwController;

    NSURL * url = [NSURL URLWithString:@"http://localhost/jsondata"];
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];

    [request setHTTPMethod:@"GET"];

/* the delegate is retained in iOS, but not necessarily in OS X so... maybe you want to make connection an ivar of self? */
    NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    /* don't you want to hold on to this? */
    [connection release], connection = 0;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)inConnection {
    if (ConnectionIsAnIvar) {
        if (self.connection != inConnection) {
            assert(0 && "connection delegate messages sent to wrong instance. threading issue or worse?");
            return;
        }
    }
    else {
        [connection release];
    }

    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

    NSArray *json = [responseString JSONValue];

    if (json != NULL) {
        NSArray *items = [json valueForKeyPath:@"d"];

        HatParseJson* hatParseJson = [[HatParseJson alloc] init];
        NSArray* hatz = [hatParseJson parseJson:items];

        NSMutableArray* newHats = [[NSMutableArray alloc] init];
        /* why not simply: 
                NSMutableArray* newHats = [hatz mutableCopy];
        */
        NSUInteger i, count = [hatz count];
        for (i = 0; i < count; i++) {
            Hat* obj = [hatz objectAtIndex:i];
            [newHats addObject:obj];

/* [obj release]; this blows up for example ... */
/* >> it should blow up. objectAtIndex: uses a get, not retain or copy */
        }
        [hatParseJson release];
        [hatController newHatJsonFinished:newReleases];
    }
    else {
        [hatController newHatJsonFinished:nil];
    }

    [responseString release];
}


[obj release] is a wrong thing to do because you are just adding objects from one array to another. Instead you should release newHats when done because you explicitly allocate it with alloc.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜