【问题标题】:objective-c memory leak + NSMutableDictionaryObjective-c 内存泄漏 + NSMutableDictionary
【发布时间】:2011-10-04 11:46:46
【问题描述】:

我正在使用带有参数的字典来发送到 Web 服务。我一直从中得到内存泄漏,尽管我为该对象做了一个释放。我的代码:

 NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

// getting an NSString
NSString *clientID = [prefs stringForKey:@"ClientID"];



//Call web service
id delegate1 = self;
AsyncWebServiceController * webService = [[[AsyncWebServiceController alloc] initWithDelegate:delegate1
                                                                                 selSucceeded:@selector(webServiceConnectionSucceeded:)
                                                                                    selFailed:@selector(webServiceconnectionFailed:)] autorelease];


NSMutableDictionary *params = [[NSMutableDictionary alloc] init]; //Memory leak here
[params setValue:clientID forKey:@"clientId"]; //Memory leak here
[params setValue:[self.jobDetails objectForKey:@"BoardId"] forKey:@"jobBoardId"];
[params setValue:[self.jobDetails objectForKey:@"Id"] forKey:@"jobId"];

[webService startRequest:@"JobReviewGet" parameters:params];

[params release];

有什么想法吗?谢谢!!

【问题讨论】:

  • 你没有发布 webService。通常人们会使用 setObject 而不是 setValue,尽管这不会导致泄漏。

标签: iphone objective-c memory-leaks nsmutabledictionary


【解决方案1】:

使用分析构建。这可能会给出一些指示。

除此之外:

  1. 您在 AsyncWebServiceController 上调用 alloc,您是否拥有它,但上面的代码没有发布。
  2. 您应该调用 setObject:forKey 而不是 setValue:ForKey。 setValue 用于 KVC。

【讨论】:

    【解决方案2】:

    你应该使用:

    - (void)setObject:(id)anObject forKey:(id)aKey;
    

    因此您的代码应如下所示:"

    NSMutableDictionary *params = 
    [[NSMutableDictionary alloc] init]; //Memory leak here
    [params setObject:clientID forKey:@"clientId"]; //Memory leak here
    [params setObject:[self.jobDetails objectForKey:@"BoardId"] forKey:@"jobBoardId"];
    [params setObject:[self.jobDetails objectForKey:@"Id"] forKey:@"jobId"];
    
    [webService startRequest:@"JobReviewGet" parameters:params];
    
    [params release];
    

    [webService startRequest:@"JobReviewGet" parameters:params]; 方法对参数做了什么,它会保留它吗?如果是这样,您还需要在那里释放它。

    还有一点你需要释放webService。

    【讨论】:

    • 为什么setObject:forKey: 而不是setValue:forKey:,两者都是NSDictionary 上的方法?我知道setValue:forKey: 调用setObject:forKey: 和删除语义,但这适用于这里的问题吗?
    • 否 setValue:forKey: 是 NSObject 的方法,setObject:forKey: 是 NSMutableDictionary 的方法 更多:stackoverflow.com/questions/1062183/…
    • 是的,不在头文件中!在 iOS 中,在 Organizer 的文档查看器中,setValue:forKey 在路径中作为实例方法:“iOS 5.0 Library>Data Management>Data Types & Collections>NSMutable Class Reference”(选项在 iOS Xcode 中双击 NSMutableDictionary文件。所以,看来苹果的文档有问题,我会提交一个bug。谢谢!
    • 似乎 setValue:forKey: 在 NSMutableDictionary 中被覆盖并且行为略有不同:“此方法使用 setObject:forKey: 将值和键添加到字典中,除非 value 为 nil 其中如果该方法尝试使用 removeObjectForKey: 删除密钥。"请注意 value 为 nil 时的差异。因此,在某些情况下,文档比阅读头文件更好。
    • 谢谢!!!它是释放方法内的参数(我保留它)和将 addValue 更改为 addObject 的组合。如果我使用自动释放,为什么要释放 Web 服务???
    【解决方案3】:

    为什么不使用便捷构造函数?

    NSMutableDictionary *params = [NSMutableDictionary dictionary]; 
    

    那么就没有必要释放它了。这应该可以解决您的问题。

    【讨论】:

      【解决方案4】:

      您是否会在某个时候发布您的 webService 对象? AsyncWebServiceController 的委托也是分配的还是保留的属性?通常应为委托分配属性以避免保留循环。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-07
        • 1970-01-01
        • 1970-01-01
        • 2011-06-07
        • 1970-01-01
        • 2013-04-18
        相关资源
        最近更新 更多