简体   繁体   English

iPhone的Objective-C:神秘内存泄漏

[英]Objective-c for the iphone: Mystery memory leak

My application seems to have 4 memory leaks (on the device, running instruments). 我的应用程序似乎有4个内存泄漏(在设备上,正在运行的仪器)。

The memory leaks seems to come from this code: 内存泄漏似乎来自以下代码:

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

EDIT : added code for getUrl 编辑 :为getUrl添加了代码

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

I am releasing all my objects as far as I can see but it's still showing this as the source of the 4 memory leaks. 我尽我所能释放所有对象,但仍将其显示为4个内存泄漏的来源。

This is on the Device running 3.1.3 这是在运行3.1.3的设备上

Is it acceptable to have a few memory leaks in your app or do they all have to go? 在您的应用程序中出现一些内存泄漏是可以接受的还是必须全部解决?

EDIT : I've added autorelease to getUrl. 编辑 :我已经添加了自动释放到的getURL。 However it still shows up with memory leaks 但是它仍然显示内存泄漏

EDIT2 : The behaviour is rather strange. 编辑2 :该行为是相当奇怪。 I launch the app and hit the button that makes this call once. 我启动应用程序和命中,使得调用一次按钮。 4 leaks are discovered. 发现了4个泄漏。 I press back and hit the button again, and keep doing this a few times, and still only 4 leaks. 我按回去并再次按下按钮,并继续执行几次,仍然只有4次泄漏。 However, if I wait a few seconds and then press the button a gain a few more times, 9 leaks are discovered. 但是,如果我等待几秒钟然后再按几次按钮,则会发现9个泄漏。 It's not a small 128 byte leak, but it's 1.61KB at this point. 这不是一个小128字节的泄漏,但此时为1.61KB。

EDIT3 : Here is the connectionDidFinishLoading 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];
}

The delegate gets the data, then transforms it (and in return passes it on to another delegate once the product is constructed) 委托获取数据,然后将其转换(并在返回其传递给一旦产品构造的另一代表)

- (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 : Something I did notice is that the object "ConnectionObject" that contains the NSUrlConnection, never seem to be deallocated. EDIT4 :我确实注意到的是,包含NSUrlConnection的对象“ ConnectionObject”似乎从未被释放。

I put a breakpoint on dealloc which calls [connection release] This dealloc is never called. 我在dealloc上设置了一个断点,该断点调用[连接释放]从未调用过此dealloc。 All the deallocs are called down the chain except for this one. 所有deallocs被称为环比下滑,除了这一个。 I tried [connection cancel] in the "connectionDidFinishLoading" call to see if that helped but not at all. 我试过[连接取消]在“connectionDidFinishLoading”打电话,看看是否能帮助,但不是在所有。

This sure is a mystery to me... 这肯定对我来说是个谜。

You are releasing something you shouldn't: 您正在发布不应该发布的内容:

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!

Remember that you should only release objects that were created using alloc , new or retain . 请记住,你应该只释放使用ALLOC, 新的保留创建的对象。 Objects returned from other methods are always in an auoreleased state (by convention). 从其他方法返回的对象始终处于auoreleased状态(按照约定)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM