2012-10-19 97 views
2

创建带有可变数组的字典时,我遇到了一些问题,例如理解内存管理。我正在使用部署目标5.1的ios6 SDK。使用NSMutableArrays创建NSDictionary的内存管理

在类“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]; 
} 

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

这是干净的吗?感谢您的任何建议!

+11

我不想成为那个人,但随着iOS6的和部署5.1,为什么你会不使用弧? –

+2

你可以发布有关崩溃的更多细节吗?你的内存管理看起来很好。另外,你应该使用'[email length]'来获得NSString的长度(什么是'len()'?)。 –

+0

@Andrew当我尝试访问字典中的数组时,我得到一个线程1 EXC_BAD_ACCESS。但是,只有当我使用上面代码中注释掉的两条发布行时。 len()是python--对不起:-) – JacobS

回答

2

我的第一个建议是使用“产品 - >分析”功能。如果你在某处泄漏或释放,它可能会给你一系列确切的事件。其次,我看不到您的方法nameAndEmailsemailGroup:之间的链接。因为我看不到连接,所以我无法告诉你autorelease是否导致问题。

当主运行循环周期时释放自动释放的对象。所以很可能你的NSDictionary正在发布。你可以通过在调试器中将内存位置设置为“watch”来做任何事情来测试它,以便在每次runloop循环时在控制台行中放置一些东西(我假设你在主运行循环中,所以纠正我如果那不是真的)。

你可以做跟踪问题的其他事情是使用在你的配置工具“植物大战僵尸”或NSZombieEnable=YES

+0

谢谢。我想先开始在运行循环中打印日志,但我无法弄清楚如何做到这一点。有什么建议? – JacobS

+0

可悲的是,我不再这么做了(我过去做这件事的方式现在不行)。我会试着去查看它,但我没有时间。 – DBD