0
votes

I have an NSMutableArray with NSManagedObjects that I pulled back from the database. What I'm trying to do is filter out certain objects in the array based on individual object properties. By filter out I mean remove from the array. The problem is that when doing a shallow copy and removing an object from arrayTwo ends up removing the NSManagedObject from the original array that I copied from. I looked up a few different ways to apply a deep copy so that I can filter out object from my second array without impacting the first array. Here is the code I'm using to do this:

 NSMutableArray *copyOfChestExercises = [[NSMutableArray alloc]initWithArray:_chestExercises      copyItems:YES];

The problem is I get the following exception:

[Exercise copyWithZone:]: unrecognized selector sent to instance 0x15679f20'

when trying to do the copy. I've read a few posts stating that I need a copyWithZone implementation to do this and have in interface. I also read a few posts claiming that NSManagedObjects cannot be copied in the manner I'm trying to do. If anyone has tips or advice on how to do this or if it can't be done the way I'm doing it, it would be much appreciated.

1

1 Answers

0
votes

To put it in a context:

-copy and -isEqual are strongly related. Both discuss two different objects to be the same. To create a copy simply means to create a second instance, which is expected to be equal to the first one.

In an object graph (it does not depend on the fact you are using CD or not) copying instances is not trivial. What does it means especially to depth? If you request a "deep copy" (up to which level?) you will find yourself copying he whole graph. It is an easy decision for attributes (and I wish, CD would do it automatically for attributes), but you cannot generalize it for relationships.

CD solves this problem by assuming two objects equal, if they have the same identity. To different objects are never equal. As a consequence you cannot copy them. Your copy would never be equal to the origin. A situation that is absurd. A complete copy (aka handling relationships, too) does not exist for objects in object graphs.

To your question:

Do not think in copies. Think in relationships. Both lists (the list to filter and the list of filtered objects) should be built-up from relationships. Let's assume you have a entity group, which contains members. Members has an attribute you want to filter on. A simple example using NSPredicate.

// The existing list
NSManagedObject *group = …; 

// The predicates used to filter. nFilter is /filter
NSPredicate *filter = …; // filters +hits
NSPredicate *nFilter = …; // filters -hits

// Get the complete (original list)
NSSet *members = [group objectForKey:@"members"];

// Get the +hit list and the -hit list
NSSet *filteredMembers = [members" filteredSetUsingPredicate:filter];
NSSet *nFilteredMembers = [members" filteredSetUsingPredicate:nFilter];

// Set the -hit list to the original object
[group setObject:nFilteredMembers forKey:@"members"]; 

// Set the +hit list to a new object
NSManagedObject *filteredGroup = …; // Create it as you need it
[filteredGroup setObject:filteredMembers for Key:@"members"];

You do not have to delete objects, because you do not want to delete them. You want to move them. So just do it.

Please take in account, that the new object does not necessarily be of the same entity type the original is of.