获取结果崩溃(使用 persistentContainer) - 核心数据目标 C

Posted

技术标签:

【中文标题】获取结果崩溃(使用 persistentContainer) - 核心数据目标 C【英文标题】:Fetch Result Crashes (using persistentContainer) - Core Data Objective C 【发布时间】:2017-02-03 21:02:50 【问题描述】:

我正在尝试从核心数据中获取结果,以便在加载视图时显示在表视图中。请求确实获取了结果,但在视图加载后立即崩溃。

with reason: '-[__NSArrayI isEqualToString:]: unrecognized selector sent to instance

自从引入 Persistent Container 以来,我找不到任何关于如何使用 Objective C 来使用它的参考资料。

我有一个简单的核心数据模型, 实体 - 带有属性的“项目” - “名称”

// ViewController.m //

@interface ViewController ()

NSMutableArray *listArray;
AppDelegate *delegate;
NSManagedObjectContext *context;
NSMutableArray *resultListArray;

@end

- (void)viewDidLoad 
[super viewDidLoad];
listArray = [[NSMutableArray alloc]init];
resultListArray = [[NSMutableArray alloc]init];
[self fetchItems];

TableView 数据源

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
return [listArray count];


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

if (resultListArray) 
    cell.textLabel.text = [resultListArray objectAtIndex:indexPath.row];


cell.textLabel.text = [listArray objectAtIndex:indexPath.row];
return cell;

获取托管上下文

- (NSManagedObjectContext *)managedObjectContext 

delegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
context = [[delegate persistentContainer]viewContext];

NSLog(@"ManagedContext Created Successfully");

return context;

保存到核心数据

- (void) saveItemMethod:(NSString*)name 

context = [self managedObjectContext];

NSManagedObject *task = [[Item alloc]initWithContext:context];

[task setValue:name forKey:@"name"];

NSString *itemString = [task valueForKey:@"name"];

[listArray addObject:itemString];

[delegate saveContext];

NSLog(@"Save successful");
NSLog(@"%@", listArray);

获取结果

- (void) fetchItems 

context = [self managedObjectContext];

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Item"];
// request.resultType = NSDictionaryResultType;

NSError *error = nil;
NSManagedObject *result = (NSManagedObject*)[context executeFetchRequest:request error:&error];

NSString *resultString = [result valueForKey:@"name"];

[resultListArray addObject:resultString];

NSLog(@"Fetch successful");
NSLog(@"%@", resultListArray);

[self.tableView reloadData];

【问题讨论】:

如果你想了解 NSPersistentContainer 看这个讲座:vimeo.com/89370886。这个讲座是从 NSPersistentContainer 存在之前开始的,但仍然非常相关。基本上 NSPersistentContainer 设置了讲座推荐的核心数据堆栈。 您需要在调试器中运行您的应用程序并打开异常断点。然后您可以准确地看到您的应用程序崩溃的位置。一旦我们看到应用程序崩溃的代码,我们就可以调试它出错的原因。 @DaveWeston 谢谢你,戴夫。我无法在表格视图中显示数据。现在已经解决了。 【参考方案1】:

错误消息表明正在对 NSArray 对象调用 isEqualToString: 方法 - 这显然不起作用(isEqualToString:NSString 方法)。

因此,您的代码将数组视为字符串。问题的根源在这里,在fetchItems 代码中:

NSManagedObject *result = (NSManagedObject*)[context executeFetchRequest:request error:&error];
NSString *resultString = [result valueForKey:@"name"];
[resultListArray addObject:resultString];

第一行错误:executeFetchRequest 返回一个NSManagedObjects 的数组(即使数组中只有一个对象)。因此,您可以使用:

NSArray *result = [context executeFetchRequest:request error:&error];
self.resultListArray = [[result valueForKey:@"name"] mutableCopy];

【讨论】:

感谢您的回复。我之前又一次尝试过。仍然崩溃,原因是:'*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array',显示数组为空。但在 fetchItems 方法中,记录 resultListArray 会在输出控制台中提供完整的项目数组。 我继续前进并将 if (resultListArray) 替换为 if ([resultListArray count] != 0) 在 numberOfRows 方法中。应用程序确实运行但未在表格视图中显示任何列表 @Rajxelton 我不确定为什么你有两个数组,listArray 和 resultListArray,但我怀疑突出的问题是你在某处使用了错误的数组。 即使使用一个数组来显示列表,我也会崩溃。你能确认我的实现是否正确吗?我找不到任何包含新引入的持久容器的 obj-c 参考。 @Rajxelton 由于记录 resultListArray 提供了完整的项目数组,因此您的 persistentContainer / context 必须正常工作。问题在于您的视图控制器/tableView 数据源方法。

以上是关于获取结果崩溃(使用 persistentContainer) - 核心数据目标 C的主要内容,如果未能解决你的问题,请参考以下文章

核心数据多对多关系导致获取的结果控制器崩溃

使用Windows事件查看器调试崩溃

NSFetchedResultsController 和 NSManagedObjectIDResultType 崩溃

快速页面刷新导致服务器崩溃一段时间

使用 UISearchDisplayController 时显示搜索结果崩溃

在 Core Data 中更改托管对象模型的属性值时崩溃