【问题标题】:Objective-c for the iphone: Mystery memory leakiphone的Objective-c:神秘的内存泄漏
【发布时间】:2011-02-24 03:50:33
【问题描述】:

我的应用程序似乎有 4 次内存泄漏(在设备上,正在运行的仪器上)。

内存泄漏似乎来自这段代码:

NSURL *url = [self getUrl:destination];
[destination release];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];

[request setHTTPMethod:@"GET"];
[request addValue:@"application/json" forHTTPHeaderField:@"content-type"];
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
[request release];

[connection release];

编辑:为 getUrl 添加代码

- (NSURL *)getUrl:(NSString *)actionUrl
{
    NSString *rawUri = [[NSString alloc]initWithFormat:@"%@/%@", kBaseUrl, actionUrl];
    NSURL *url = [[[NSURL alloc] initWithString:rawUri] autorelease];
    [rawUri release];
    return url;
}

据我所知,我正在释放我的所有对象,但它仍然显示这是 4 次内存泄漏的来源。

这是在运行 3.1.3 的设备上

在您的应用程序中出现一些内存泄漏是否可以接受,还是必须全部解决?

编辑:我已将 autorelease 添加到 getUrl。但是它仍然会出现内存泄漏

EDIT2:行为相当奇怪。我启动应用程序并点击一次调用的按钮。发现4个泄漏点。我按回并再次按下按钮,并继续这样做几次,仍然只有 4 次泄漏。但是,如果我等待几秒钟,然后再按几次增益按钮,就会发现 9 个泄漏。这不是一个小的 128 字节泄漏,但此时它是 1.61KB。

EDIT3:这里是connectionDidFinishLoading

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    SBJSON *jsonParser = [[SBJSON alloc] init];
    NSString *jsonString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
    [receivedData setLength:0];
    [receivedData release];
    [self.delegate dataReceived:[jsonParser objectWithString:jsonString]]; // See method below
    [jsonParser release];
    [jsonString release];
}

委托获取数据,然后对其进行转换(并在构建产品后将其传递给另一个委托)

- (void)dataReceived:(id)data
{
    NSMutableArray *myObjects = [[NSMutableArray alloc]init];
    ObjectFactory *objectFactory = [[ObjectFactory alloc]init];

    // Only one object
    if ([data isKindOfClass:[NSDictionary class]])
    {
        Object *object = [objectFactory buildObject:data];
        [myObjects addObject:object];
        [object release];
    }

    // Multiple objects
    if ([data isKindOfClass:[NSArray class]])
    {
        for (NSDictionary *objectSrc in data)
        {
            Object *object = [objectFactory buildObject:post];
            [myObjects addObject:object];
            [object release];
        }
    }
    [objectFactory release];
    [self.delegate objectsReceived:myObjects];
}

EDIT4: 我确实注意到包含 NSUrlConnection 的对象“ConnectionObject”似乎从未被释放。

我在 dealloc 上放置了一个断点,它调用 [connection release] 这个 dealloc 永远不会被调用。除了这个之外,所有的 deallocs 都会被调用。 我在“connectionDidFinishLoading”调用中尝试了[连接取消],看看是否有帮助,但根本没有。

这对我来说肯定是个谜......

【问题讨论】:

标签: iphone objective-c memory memory-leaks


【解决方案1】:

你发布了一些你不应该发布的东西:

NSURL *url = [self getUrl:destination]; 
// the returned url should have been autoreleased by the getUrl: method
// so you shouldn't release it again

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];

[url release]; // don't do this!

请记住,您应该只释放使用 allocnewretain 创建的对象。从其他方法返回的对象始终处于 auoreleased 状态(按照惯例)。

【讨论】:

  • 我是这么想的,虽然我想到这可能是 -getUrl 的错误,它分配了一个 NSURL 并且没有释放,这意味着调用 [url release];实际上会导致引用计数为 0,这就是您想要的!如果是这种情况,那么您需要在 -getUrl 中自动释放,然后在调用时保留其返回的 NSURL。
  • 分配(临时)对象的方法应该从不返回该对象而不首先调用它的自动释放。 从不
  • "大卫:不,这不是你想要的。你想要的是返回一个调用者不必释放的对象,因为这是调用者所期望的。或者你可以改变从 getUrl: 到 newURL: 的方法名称。顺便说一下,忘记保留计数。只考虑所有权。保留计数通常会产生误导。例如,如果您在 getURL 中自动释放 URL:保留计数仍将至少为 1返回。
  • Jeremy,我很清楚不能将引用计数作为内存管理的一种手段。我也建议只考虑对象所有权原则(遵守该原则可以防止经常遇到的大多数内存泄漏),但我提到引用计数只是为了量化分配、新闻、保留和释放的数量。
猜你喜欢
  • 2013-06-26
  • 2013-07-25
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 1970-01-01
相关资源
最近更新 更多