【问题标题】:Block based enumeration getting BAD_ACCESS基于块的枚举获取 BAD_ACCESS
【发布时间】:2013-07-22 21:00:10
【问题描述】:

我有一个基于块的枚举设置来遍历一个 NSDictionaries 数组,如下所示:

__block NSURL *contentURL;

 //This method of enumerating over the array gives the bad_access error
[documents enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

    NSString *aName = [(NSDictionary *)obj objectForKey:@"Name"];

    if([aName isEqualToString:name]) {

        contentURL = [NSURL URLWithString:[(NSDictionary *)obj objectForKey:@"Content"]];
        *stop=YES;
    }
}];

NSLog(@"Content URL for issue with name %@ is %@", name, contentURL);

如果我使用这种方法,当我尝试在 NSLog 语句中打印出来时,我会在contentURL 上收到 EXC_BAD_ACCESS 错误。

但是,如果我这样枚举数组:

NSURL *contentURL;

//This method of enumerating over the array works fine
for (NSDictionary *obj in documents) {

    NSString *aName = [obj objectForKey:@"Name"];

    if([aName isEqualToString:name]) {

        contentURL = [NSURL URLWithString:[obj objectForKey:@"Content"]];

    }
}

NSLog(@"Content URL for issue with name %@ is %@", name, contentURL);

一切正常。为什么是这样?

【问题讨论】:

  • I get a EXC_BAD_ACCESS error on contentURL. 这是否意味着调试器停止分配?
  • 对不起,不在作业中,当我尝试在 NSLog 中打印时
  • 使用您的代码,我只能怀疑变量name 是问题所在。我可以看到它的定义以及你在哪里给它赋值吗?另外,您可能正在使用手动引用计数吗?

标签: objective-c nsarray objective-c-blocks enumeration


【解决方案1】:

不久前我遇到了类似的问题。

事实证明,一些基于块的枚举方法将枚举包装在自动释放池中。由于您要分配一个自动释放的对象,它会在 -enumerateObjectsUsingBlock: 返回之前被释放。

(我遇到了-[NSDictionary enumerateKeysAndObjectsUsingBlock:的问题,但同样的原理在这里适用)

试试这个:

contentURL = [[NSURL alloc] initWithString:[(NSDictionary *)obj objectForKey:@"Content"];

出于兴趣,您在使用 ARC 吗?如果你是,我希望它会在分配时添加-retain

编辑: 您正在使用 ARC,所以这不是您问题的答案。分配给 __block 变量将保留该对象(除非您在 ARC 中遇到错误,这不太可能。您提供的代码在使用 Apple LLVM 5.0 编译时没有此问题)。

您的问题很可能出在其他地方,使用便捷构造函数进行更改只是掩盖了问题。

同样,在枚举期间设置的自动释放池可能会揭示代码中其他地方引起的问题。它解释了为什么切换到使用快速枚举似乎可以解决问题,但和以前一样,它可能只是掩盖了代码中其他地方引起的问题。

我将在此处留下答案,因为有关自动释放池的信息可能仍然与偶然发现此问题的人相关。

【讨论】:

  • 你的意思是-[NSArray enumerateObjectsUsingBlock:]
  • 哎呀。我遇到了 NSDictionary 的问题,但 NSArray 可能会做同样的事情。
  • 原来你对过早的释放问题很了解。便利构造函数可能很棘手。
  • 新的分配方法修复了它。愚蠢的便利构造函数:P
  • 如果您通过 __autoreleasing 参数通过引用返回,则在 ARC 下尤其令人讨厌。
【解决方案2】:

如果您使用 ARC,正如您所说的那样,那么您显示的代码不会产生您描述的问题。您一定是在其他地方有问题,或者您的代码与您描述的不一样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多