如何在执行低级别http工作时改进内存管理

时间:2011-01-30 16:33:35

标签: objective-c http memory-management

我开始清理我工作的旧原型,它正在进行大量低级别的http工作。我遇到的问题是如何以及何时在下面的“connectionDidFinishLoading”方法中进行发布。我只在if中创建了一些项目,但是当我在方法调用之前释放它们时,我得到了几个BAD ACCESS错误,并想知道我应该在这种情况下进行内存管理。

- (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)connectionDidFinishLoading:(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 {

}

提前谢谢

2 个答案:

答案 0 :(得分:1)

内联的一些更新和评论:

- (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];
}

答案 1 :(得分:0)

[obj release]是一件错误的事情,因为你只是将对象从一个数组添加到另一个数组。相反,您应该在完成后释放newHats,因为您使用alloc显式分配它。