1

对于我的表格视图,我正在进行以下操作(释义)

。H

@interface OptionsView : UIView <UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, retain) NSArray *dataSource;

.m

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {

        ...

        self.dataSource = [NSArray arrayWithObjects:options, sections, sponsor,  nil];
    }
    return self;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(self.dataSource) {
        NSArray *ds = [self.dataSource objectAtIndex:indexPath.section];
        NSDictionary *d = [ds objectAtIndex:indexPath.row];
        ActionBlock a = [d objectForKey:ACTION]; // <-- Thread 1: EXC_BAD_ACCESS (code=2, address=0x802)
        if(a != nil) a();
    }
}

你可以看到我didSelectRowAtIndexPath的我得到了一个,EXC_BAD_ACCESS但我不知道为什么。因为我使用的是 arc,所以它不是僵尸问题(已经检查过)。

使用断点,我看到self.dataSource它在初始化后就存在,但在需要时不存在。它也没有显示出来<nil>,它只是空白。此外,这在调试中有效,但在发布中无效,那是什么意思?

** 编辑添加截图 **

你会注意到既没有也没有ds出现d……奇怪吗? xcode 调试

4

2 回答 2

2

所以我可以看到有两个地方可能会导致问题。首先,什么是ACTION?它是某种 NSString 吗?只是想确保您使用的是有效的密钥对象。其次,(更可能是问题),它看起来像是ActionBlock您存储在集合数组中的某种代码块。您是否在将该块存储到数组/字典中之前复制该块?您必须复制您打算保留(存储)比创建它的范围更长的任何块。这很容易做到。例如:

void (^NewBlock)(void) = [^{
    ....code....
} copy];

交替:

void (^NewBlock)(void) = ^{
    ....code....
};

[dictionary setObject:[NewBlock copy] forKey:ACTION]; //Assuming #define ACTION @"action"

这会将其复制到堆上以便可以存储。如果您不复制它,那么无论何时您尝试在创建它的范围之外引用该块,您都会得到 BAD_EXC_ACCESS。

于 2012-05-31T12:50:26.313 回答
0

看来您使用的是 UIViewController 而不是 UITableViewController。如果我没记错的话,你必须去检查器并将委托和数据源从 tableView 拖到 UIViewController。我不记得确切,我不在我的电脑上,但我确信在我开始为我拥有的每个 tableView 使用 UITableViewController 之前我做了几次。

哦,我不会使用 dataSource 作为数组的名称。只是为了防止命名冲突。

于 2012-05-31T12:31:01.407 回答