There is an application that has a list of employees, and each employee may have several tasks. When you click on the employee should open his task. There is an error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'property = "task"; desired type = NSSet; given type = _PFArray; value =

Code for employee controller:

#import "EmployeesViewController.h" #import "Tasks.h" #import "AppDelegate.h" #import CoreData; #import "Employees.h" #import "TasksViewController.h" @interface EmployeesViewController () @property(strong) NSMutableArray *employees; @end @implementation EmployeesViewController -(NSManagedObjectContext *) managedObjectContext{ NSManagedObjectContext *context=nil; id delegate = [[UIApplication sharedApplication] delegate]; if ([delegate performSelector:@selector(managedObjectContext)]) { context=[delegate managedObjectContext]; } return context; } -(void) viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; NSManagedObjectContext *managedObjectContext = [self managedObjectContext]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Employees"]; self.employees=[[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy]; [self.tableView reloadData]; } - (void)viewDidLoad { [super viewDidLoad]; } -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ if([segue.identifier isEqualToString:@"empToTasks"]){ TasksViewController *task = segue.destinationViewController; task.emp = [self.employees objectAtIndex:self.tableView.indexPathForSelectedRow.row]; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } -(BOOL) tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{ return YES; } -(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ NSManagedObjectContext *context = [self managedObjectContext]; if (editingStyle==UITableViewCellEditingStyleDelete) { [context deleteObject:[self.employees objectAtIndex:indexPath.row]]; NSError *error=nil; if (![context save:&error]) { NSLog(@"Не удалось! %@ ", error); return; } [self.employees removeObjectAtIndex:indexPath.row]; [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; } } -(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.employees.count; } -(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell= [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; NSManagedObject *employees = [self.employees objectAtIndex:indexPath.row]; [cell.textLabel setText: [employees valueForKey: @"name"]]; [cell.detailTextLabel setText:[employees valueForKey:@"position"]]; return cell; } @end 

Code for task controller:

  #import "TasksViewController.h" #import "Tasks.h" #import "AppDelegate.h" @import CoreData; #import "EmployeesViewController.h" @interface TasksViewController () @end @implementation TasksViewController -(NSManagedObjectContext *) managedObjectContext{ NSManagedObjectContext *context=nil; id delegate = [[UIApplication sharedApplication] delegate]; if ([delegate performSelector:@selector(managedObjectContext)]) { context=[delegate managedObjectContext]; } return context; } -(void) viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; } - (void)viewDidLoad { [super viewDidLoad]; NSManagedObjectContext *managedObjectContext = [self managedObjectContext]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Tasks"]; self.emp.task=[managedObjectContext executeFetchRequest:fetchRequest error:nil]; [self.tableView reloadData]; } -(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } -(BOOL) tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{ return YES; } -(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.emp.task.count; } -(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *CellIdentifier = @"Cell1"; UITableViewCell*cell1 =[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; NSManagedObject *tasks = [self.emp.task.allObjects objectAtIndex:indexPath.row]; [cell1.textLabel setText: [tasks valueForKey: @"task"]]; return cell1; } 

The error is contained here:

  NSManagedObjectContext *managedObjectContext = [self managedObjectContext]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Tasks"]; self.emp.task=[managedObjectContext executeFetchRequest:fetchRequest error:nil]; [self.tableView reloadData]; 
  • In the question you brought too much unnecessary code and at the same time did not show what model you have and how it is interconnected - Tikhonov Alexander
  • {NSManagedObjectContext * managedObjectContext = [self managedObjectContext]; NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] initWithEntityName: @ "Tasks"]; self. emp. task = [managedObjectContext executeFetchRequest: fetchRequest error: zero]; [self. Tableview reloadData];} here I have a mistake - Maria
  • Um, an error can then be generated in this place, but the problem itself is in another place. The code that you gave, it is impossible to understand what is happening in your project. ps can attach a project file - I'll watch it - Tikhonov Alexander
  • @TikhonovAlexander please tell me what to show you or what to explain that would be clearer - Maria
  • Judging by the content of this test project, fill it somewhere, I will download and see the code. - Tikhonov Alexander

1 answer 1

Yes, indeed, the error was in the place where you indicated, but without presenting the model it was difficult to understand.

 [managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

Returns an array of tasks, that is, NSArray. And the Employees model has a lot of stuff, I mean NSSet<Tasks *> *task;

Accordingly, such a piece of code leads to an error

 self.emp.tasks = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; // Error 

The correct version is presented below.

 NSManagedObjectContext *managedObjectContext = [self managedObjectContext]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Tasks"]; NSError *error = nil; NSArray *allTasks = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; if (error == nil ) { NSLog(@"Success: Resulting array of tasks:\n%@", allTasks); self.emp.task = [NSSet setWithArray:allTasks]; } else { NSLog(@"Failure: something went wrong: %@", error); } [self.tableView reloadData]; 

Also be careful with adding new elements to emp.tasks. self.emp.task.addObject() will cause an error.

If my memory serves me, the addition is done by copying the old NSSet , adding a new Task to this NSSet and assigning self.emp.tasks = newSet;