【问题标题】:Memory management creating an NSDictionary with NSMutableArrays使用 NSMutableArrays 创建 NSDictionary 的内存管理
【发布时间】:2012-10-19 19:47:29
【问题描述】:

在使用可变数组创建字典时,我无法理解内存管理。我正在使用 ios6 SDK 和部署目标 5.1。

在“Group”类的实现中,“namesAndEmails”方法构建了一个数组“emails”,其中包含带有电子邮件的 Person 对象的电子邮件地址。如果 Person 对象没有电子邮件,则将 Person 名称添加到另一个数组“namesWithNoEmail”。数组在字典中返回。

#import "Group.h"
@implementation Group 

-(NSDictionary*) namesAndEmails {
    NSMutableArray  *emails = [[NSMutableArray alloc] initWithCapacity:0] ;
    NSMutableArray  *namesWithNoEmail = [[NSMutableArray alloc] initWithCapacity:0];
    NSString *email;
    NSString *name;
    for (Person *p in allPersons) {
        email = p.email;
        name = p.name;
        if ([email length]==0) {
            [namesWithNoEmail addObject:name];
        } else {
            [emails addObject:email];
        }
    }
    NSArray *keys = [NSArray arrayWithObjects:@"emails",@"names", nil];
    NSArray *objects = [NSArray arrayWithObjects:emails, namesWithNoEmail, nil];
    //[emails release];
    //[namesWithNoEmail release];

     return [NSDictionary dictionaryWithObjects:objects forKeys:keys];
}

我希望在代码中的其他地方向一组人发送电子邮件,因此我调用 emailGroup 方法,该方法通过在组中调用“namesAndEmails”来获取字典。

-(void) emailGroup:(Group*) g {

    NSDictionary *emailInfo = [g namesAndEmails];
    guestsWithNoEmail = [emailInfo objectForKey:@"names"];
    guestEmails = [emailInfo objectForKey:@"emails"];

   int nGuestsWithNoEmail = [guestsWithNoEmail count];

   if (nGuestsWithNoEmail > 0) {
      UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"No emails" message:@"" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
      [alert show];
   }

    // some more code here


    MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
    picker.mailComposeDelegate = self;
    [picker setSubject:subject];
    [picker setMessageBody:@"" isHTML:NO];
    [picker setToRecipients:guestEmails];
    [[self delegate ] presentModalViewController:picker animated:YES];
    [picker release];
}

据我了解,“namesAndEmails”中的 [NSDictionary dictionaryWithObjects:objects forKeys:keys] 返回一个自动发布的字典。但是,如果我释放“emails”和“namesWithNoEmail”数组,为什么我的代码会崩溃?我认为字典在添加数组后将拥有数组的所有权,因此在方法中释放数组是安全的。我想这不正确,但为什么呢?

这是一种更干净的方法吗?谢谢你的建议!

【问题讨论】:

  • 我讨厌成为那种人,但是对于 iOS6 和 5.1 的部署,你为什么不使用 ARC?
  • 您能否发布有关崩溃的更多详细信息?您的内存管理看起来不错。此外,您应该使用[email length] 来获取 NSString 的长度(len() 是什么?)。
  • @Andrew 当我尝试访问字典中的数组时,我得到一个线程 1 EXC_BAD_ACCESS。但只有当我使用上面代码中注释掉的两条发布行时。 len() 是 python - 对此感到抱歉:-)
  • @Paul 谢谢。也许我应该,但现在我只想了解这个问题。
  • 你能告诉我们你访问数组的代码吗?就像我说的,您发布的内容(除了 len())没有任何问题。或者,您问题中的代码是您正在编译的 实际 代码吗? len() 在那里让我不这么认为。请复制/粘贴有问题的真实代码。

标签: iphone objective-c cocoa-touch ios5 memory-management


【解决方案1】:

我的第一个建议是使用“产品->分析”功能。如果你在某处泄漏或过度释放,它可能会给你确切的事件链。

其次,我看不到您的方法nameAndEmailsemailGroup: 之间的链接。因为我看不到连接,所以我无法告诉您是否是自动释放导致了问题。

当主运行循环循环时,自动释放的对象会被释放。所以很有可能你的NSDictionary 被释放了。您可以通过在调试器中将内存位置设置为“监视”到每次运行循环时在控制台行中打印某些内容(我假设您在主运行循环中,所以请纠正我)来测试这一点如果那不是真的)。​​

您可以采取其他措施来跟踪问题,例如在仪器中使用“Zombies”或在您的配置中使用 NSZombieEnable=YES

【讨论】:

  • 谢谢。我想首先在运行循环循环时将一些内容打印到日志中,但我不知道该怎么做。有什么建议吗?
  • 遗憾的是我不再这样做了(我以前的做法现在行不通了)。我本来打算去查查的,但是我没有时间。
猜你喜欢
  • 2013-07-10
  • 2023-03-29
  • 1970-01-01
  • 2012-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-23
相关资源
最近更新 更多