NSDictionary 内存泄漏

发布于 2025-01-02 10:06:27 字数 1572 浏览 1 评论 0原文

我的代码有一个问题,我一生都无法弄清楚,即使这里之前的所有线程也无法解决。 我正在从 JSON 源中提取数据并将其放入 NSDictionary 中,如教程和 SO 中所述。在分析应用程序时,我注意到此 NSDictionary 引起的内存泄漏,但在此函数结束时释放它会导致应用程序崩溃。有什么建议吗? (顺便说一句:我对 Obj-C 和一般编程都很陌生,所以这段代码主要是从各种来源挑选出来的。)

- (void)fetchedData:(NSData *)responseData {
    //parse JSON for empty return
    if([responseData length] != 0){

        NSError* error = nil;
        //Convert JSON data to Obj-C
        NSDictionary* allShotData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];

        NSString *player = [[allShotData objectForKey:@"player"] objectForKey:@"name"];
        NSString *shotDribbblePage = [allShotData objectForKey:@"url"];

        NSString *shotTitle = [allShotData objectForKey:@"title"];
        NSURL *imageURL = [NSURL URLWithString:[allShotData objectForKey:@"image_url"]];
        shotPageURL = [shotDribbblePage retain];


        //***********************
        //  Setup a-sync loading of shot
        //***********************

        NSOperationQueue *queue = [NSOperationQueue new];
        NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadImage:) object:imageURL];   
        [queue addOperation:operation]; 
        [operation release];
        [queue release];
    }
    else{
        airballCount++;
        if (airballCount <= 20) {
            [self getDribbbleData];
        }
        else{
            NSLog(@"Too many airballs. Bailing out");
            [self showNoConnectionModal];
        }
    }
}

I have a problem with my code that for the life of me I can't figure out, not even with all previous threads here on SO.
I'm pulling data from a JSON source and putting it in an NSDictionary as stated in tutorials and on SO. When profiling the app, I notice a memory leak caused by this NSDictionary but releasing it at the end of this function crashes the app. Any suggestions?
(By the way: I'm new to Obj-C and programming in general, so this code is mostly cherrypicked from various sources.)

- (void)fetchedData:(NSData *)responseData {
    //parse JSON for empty return
    if([responseData length] != 0){

        NSError* error = nil;
        //Convert JSON data to Obj-C
        NSDictionary* allShotData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];

        NSString *player = [[allShotData objectForKey:@"player"] objectForKey:@"name"];
        NSString *shotDribbblePage = [allShotData objectForKey:@"url"];

        NSString *shotTitle = [allShotData objectForKey:@"title"];
        NSURL *imageURL = [NSURL URLWithString:[allShotData objectForKey:@"image_url"]];
        shotPageURL = [shotDribbblePage retain];


        //***********************
        //  Setup a-sync loading of shot
        //***********************

        NSOperationQueue *queue = [NSOperationQueue new];
        NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadImage:) object:imageURL];   
        [queue addOperation:operation]; 
        [operation release];
        [queue release];
    }
    else{
        airballCount++;
        if (airballCount <= 20) {
            [self getDribbbleData];
        }
        else{
            NSLog(@"Too many airballs. Bailing out");
            [self showNoConnectionModal];
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

撩起发的微风 2025-01-09 10:06:27

这里:

shotPageURL = [shotDribbblePage retain];

您可能应该使用访问器:

self.shotPageURL = shotDribbblePage;

我应该真的强调您应该在任何地方使用访问器,因为它们会为您进行引用计数(例外:不在初始化器和dealloc中)。正如 beryllium 还指出的那样,如果没有访问器,您可以手动进行引用计数。这采用基本形式:

[shotPageURL release];
shotPageURL = [shotDribbblePage retain];

如果是返回的字典的内容泄漏,那么这就是您在读取时使用/引用内容的方式(过度保留)。

如果您在并发上下文中使用您的类,那么您通常需要锁。

如果您正在从辅助线程加载 UIImage 或以其他方式与 UIKit 对象进行交互,那就不好了。

Here:

shotPageURL = [shotDribbblePage retain];

you should probably use the accessor:

self.shotPageURL = shotDribbblePage;

I should really emphasize that you should use your accessors everywhere since they do your ref counting for you (exception: not in initializers and dealloc). As beryllium also notes, you could do your ref counting manually if there is no accessor. That takes the basic form:

[shotPageURL release];
shotPageURL = [shotDribbblePage retain];

If it's the contents of the returned dictionary that are leaking, then it's how you have used/referenced the contents when read (over-retain).

If you're using your class in a concurrent context, then you will usually need a lock.

If you're loading a UIImage or otherwise interacting with UIKit objects from a secondary thread -- that's not good.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文