【问题标题】:ios ARC table bad accessios ARC 表访问错误
【发布时间】:2012-05-29 18:04:28
【问题描述】:

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

.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 在它初始化之后就存在,但在需要它的时候不存在。它也不显示为&lt;nil&gt;,它只是空白。此外,这在调试中有效,但在发布中无效,这是什么意思?

** 编辑添加屏幕截图 **

您会注意到dsd 都没有出现.. 奇怪吗?

【问题讨论】:

  • 这可能不是一个修复,但对于 ARC,它通常使用弱/强而不是分配/保留属性
  • 我不确定它在 xcode 中是否相同,但我也从 Visual Studio 开发中知道,发布版本中的调试符号根本不可靠
  • 你能记录下dsd 的值吗?另一个帮助是将失败的行包装在 @try/@catch 块中并检查异常的描述并调用StackSymbols。
  • 如果它在 [d objectForKey:ACTION] 上崩溃;那么“self.dataSource”和“ds”应该仍然存在。
  • @all 截图已添加。这可能会使我的情况更加清晰。

标签: ios uitableview memory-management automatic-ref-counting exc-bad-access


【解决方案1】:

所以我可以看到有两个地方可能会导致问题。首先,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 任何时候你试图引用它创建的范围之外的块。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 任何对象都可以作为表视图的数据源和委托。您不需要表格视图控制器。
    • 是的,当然任何对象都可以。我只是说无论这些对象是什么,tableView 都必须知道它们。这就是为什么必须完成连接的原因。再说一次,我已经很久没有这样做了,所以我可能会生疏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    • 2014-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多