在 iOS 中对来自 Core Data 的实体的 NSArray 进行快速枚举时出现运行时错误

Posted

技术标签:

【中文标题】在 iOS 中对来自 Core Data 的实体的 NSArray 进行快速枚举时出现运行时错误【英文标题】:Getting runtime error when doing fast enumeration over an NSArray of entities from Core Data in iOS 【发布时间】:2013-11-24 04:49:21 【问题描述】:

我有一个 NSArray 类型的 NSManagedObject 对象,这些对象是从我在 Core Data 中执行的获取结果返回的。 NSArray 包含对象,因为我可以在查询后通过将 NSArray 的内容打印到控制台来验证这一点。然而,我的问题是我无法使用从查询中检索到的实体类型的对象对这个数组进行快速枚举。我在运行时遇到的确切错误如下:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[My_Entity_Name countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0xa9f0090'

我正在使用的 for 循环甚至无法运行,因为它在 for 循环条件下中断:

for (MyEntityType *entityType in self.entityArray) 
...

我用来填充数组 self.entityArray 的实际 fetch 命令是:

self.entityArray = [[Singleton sharedInstance] retrieveEntities:self.mainEntity.relationshipEntity.relationshipEntityId];

反过来,这就是我的 retrieveEntity 方法的样子:

- (NSArray *)retrieveEntities:(NSNumber *)relationshipEntityAttributeId 

    NSManagedObjectContext *context = [[DataEngine sharedInstance] managedObjectContext];
    NSError *error;

    // Create fetch request
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:ENTITY_NAME inManagedObjectContext:context];
    [fetchRequest setEntity:entity];

    // Create predicate
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"relationshipEntity.relationshipAttributeId == %@", relationshipEntityAttributeId];
    [fetchRequest setPredicate:pred];

    NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
    if ([items count]>0) 
        return items[0];
     else 
        return nil;
    

为什么会出现上述错误?

【问题讨论】:

添加的代码并没有真正的帮助,因为它使用了我们不知道的方法retrieveEntity(嗯,至少对我来说)。 我已更新代码以包含附加方法。 【参考方案1】:

代码中有一个错字,你填充 self.entityAray,然后从 self.entityArray 中绘制。这是您的示例中的一个小错字,或者它解释了您的错误。在查找 self.entityArray 时,由于拼写错误而无法找到它 en 抛出 NSInalidArgumentException

【讨论】:

感谢您指出,这是我在发布问题时的拼写错误。【参考方案2】:

它说明错误消息中的错误。

你有一个班级My_Entity_NameMy_Entity_Name 的实例分配给属性self.entityArray。当您执行for (MyEntityType *entityType in self.entityArray) 时,它会将-countByEnumeratingWithState:objects:count: 消息传递给实例,并且您会收到无法识别的选择器错误。

我会寻找分配了值的位置(self.entityArray = …[self setEntityArray:…]),以找出self.entityArray 是如何获得错误值的。也许您应该发布您是如何进行提取的,或者是否有其他方式可以为 self.entityArray 分配值。


更新

我不确定-[Singleton retrieveEntity:] 做了什么。它不是一个属于标准框架的类,而且我不知道有任何使用这种通用命名的第三方库。

我可以告诉你的是,基于方法名称-retrieveEntity:,它看起来像返回单个对象而不是对象数组。通常返回数组的方法是复数的,所以我希望名称更像-retrieveEntities:

您遇到了异常,因为self.entityArray 不包含NSArray。方法名称看起来不像会返回一个数组。

您确定[[Singleton sharedInstance] retrieveEntity:…] 应该返回NSArray 吗?或许您应该发布-retrieveEntity: 的代码。


更新

你没有返回一个数组。

NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
if ([items count]>0) 
    return items[0];
 else 
    return nil;

如果 items 数组有任何元素,则返回第一个元素。这就是items[0] 所做的。

如果要返回数组,请将其更改为:

NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
if ([items count]>0) 
    return items;
 else 
    return nil;

请注意,我已将 return items[0];(返回数组的第一个元素)替换为 return items;(返回整个数组)。

【讨论】:

感谢您的回答。我添加了代码,展示了如何从 fetch 中填充数组。 [Singleton retrieveEntity] 是我的 Singleton 实例,它调用我的方法从 Core Data 中检索结果。我已经按照您的建议更改了名称,以使其功能更准确(即使其复数,因为它应该返回多个结果。我还包括了执行实际提取的方法。 如果我的数组只包含一个对象,我会收到这个错误吗?我问这个是因为如果我执行 NSLog:(@"Number of objects in array are: %d", [self.entityArray count]);我注意到这一行也出现了同样的错误。

以上是关于在 iOS 中对来自 Core Data 的实体的 NSArray 进行快速枚举时出现运行时错误的主要内容,如果未能解决你的问题,请参考以下文章

IOS/objective-c/core-data:如何从相关实体获取属性

在单个 NSTableView (Core-Data) 中显示来自多个实体的数据

ios如何在Core Data的实体中添加事件?

将来自不同表(实体)的 2 个特定托管对象与 Core Data 保持关联的最佳方法是啥?

iOS 使用关系检索和排序 Core Data 实体

iOS Core Data Predicate 用于根据相关数据进行过滤