0

所以在我的视图控制器中,我运行代码来填充客户(自定义类)对象的 NSArray。这个自定义类的对象属于另一个名为 Address 的自定义类(客户有一个帐单地址和一个送货地址)。在视图控制器中,当列表中的客户被选中时,它会向新的视图控制器传递一个客户对象,如下所示:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    InfoViewController *customerinfoViewController = [[InfoViewController alloc] initWithStyle:UITableViewStyleGrouped andCustomer:[[[customers objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] retain]];
    [self.navigationController pushViewController:customerinfoViewController animated:YES];
    [customerinfoViewController release];
}

我第一次在运行应用程序时访问这个视图控制器,它工作正常。但是,当我重新访问视图控制器时,会发生一些有趣的事情。应用程序崩溃,无法识别的选择器发送到实例 0x00whatever。使用 xCode 中的鼠标悬停调试功能,我发现客户的 shipAddress 变量的第一个对象的类型从 NSString 更改为 NSIndexPath。这不会发生在客户的 billAddress 对象上。有人知道这里发生了什么吗?似乎我可能遇到了内存管理问题,但在我撕开我的代码跟踪所有保留和释放之前,我肯定希望对此进行确认......

编辑:更多信息在这里。使用以下代码,我在类级别有一个 NSMutableArray。在循环的每次迭代中,我都会遍历 XML 中的节点(效果很好)。每次检测到一个新字母作为名称的第一个字母时,我都会创建一个新的子数组并将客户添加到其中,从而为我的类级别 NSMutableArray (customers) 填充每个检测到的字母表中的客户子数组。我的问题是关于循环客户对象的保留和释放。Clang Static 说客户有一个过度保留的错误,但是当我根据 Clang 修复它时,循环崩溃了。是什么赋予了?相关代码如下:

DDXMLDocument *rootDoc = [[[DDXMLDocument alloc] initWithData:xmlData options:0 error:nil] autorelease];
NSArray *elems = [rootDoc nodesForXPath:@"QBXML/QBXMLMsgsRs/CustomerQueryRs/CustomerRet" error:nil];
DDXMLNode *node;
sectionTitles = [[[NSMutableArray alloc] initWithCapacity:1] retain]; // Letters for UITableView section titles
NSMutableArray *subArray;
NSString *lastchar = @"A";
NSString *testchar; 
int indexCount = -1;
customers = [[[NSMutableArray alloc] initWithCapacity:[elems count]] retain];
Customer *newCust;
for (int i = 0; i < [elems count]; i++) {
    node = [elems objectAtIndex:i];
    newCust  = [[Customer alloc] initWithCustomerRetNode:node];
    testchar = [[newCust fullName] substringToIndex:1];
    if (i == 0 || ![[testchar uppercaseString] isEqualToString:lastchar]) {
        [sectionTitles addObject:testchar];
        lastchar = testchar;
        indexCount++;
        subArray = [[NSMutableArray alloc] initWithCapacity:1];
        [customers addObject:subArray];
        [subArray release];
        [[customers lastObject] addObject:[newCust retain]];
    }
    else {
        [[customers lastObject] addObject:[newCust retain]];
    }
    [newCust release];
}

注意:这段代码在大多数情况下都有效,但 clang 不喜欢它。

编辑: Customer 类中的地址是这样分配的(在 Clang 修复后现在不起作用)

...
else if ([tempname isEqualToString:@"BillAddress"])
  billAddress = [billAddress initWithAddressNode:tempnode];
else if ([tempname isEqualToString:@"ShipAddress"])
  shipAddress = [shipAddress initWithAddressNode:tempnode];
...
4

1 回答 1

1

听起来你有一个过度释放的问题,所以是的内存管理,你可能过度释放了你存储对象的数组。虽然不能从代码片段中真正看出。你必须去查看代码并找到源代码。使用 Clang 静态分析器也可能对您有所帮助。

于 2009-07-14T17:59:01.883 回答