Re: Core Data: Dual-Inverse Relation Possible in Modeler?
Re: Core Data: Dual-Inverse Relation Possible in Modeler?
- Subject: Re: Core Data: Dual-Inverse Relation Possible in Modeler?
- From: email@hidden
- Date: Fri, 21 Oct 2005 13:35:17 -0700
OK, here is the code in the NSManagedObject I implemented (Named
NSAttacker for fun)
It can be used in a inverse-inverse relation where the to-many
relation is the same name and same type of entity or object.
As en example a color object has a to-many relation called inverse.
When color called white is created, another color black is set as its
inverse, so automatically, like a traditional inverse relation,
blacks' inverse is also set the white. If there are also other
logical inverses maybe verbs or nouns that have synonyms (like
'bright' being inverse of 'black' also)
they can be set, and the one on the other end will get set its
inverse automatically, as long as they are the same type of entity or
object.
The following is a kind of template for the object, you can just
redefine the names or just use find and replace
match your own object name and keys, it doesn't check entity type so
be careful
===============================================
//This will need to change to reflect the different names of your
object and key value pair
//And accessor method to match your key name - here its enemies
#import "NSAttacker.h"
#pragma mark
#define __RELATED_OBJECT_NAME NSAttacker
#define __RELATIONSHIP_NAME @"enemies"
#define __setOBJECTNAME setEnemies
#define __add_RELATED_OBJECT addEnemiesObject
#define __remove_RELATED_OBJECT removeEnemiesObject
#pragma mark
@implementation __RELATED_OBJECT_NAME
- (void)__setOBJECTNAME:(NSSet *)objectsToAdd //called by array
controller
{
//Filter out the removals
NSMutableSet *oldObjectsForRemoval = [NSMutableSet
setWithCapacity:[objectsToAdd count]];
[oldObjectsForRemoval setSet:[self
valueForKey:__RELATIONSHIP_NAME]];
[oldObjectsForRemoval minusSet:objectsToAdd];
//Filter out the additions
NSMutableSet *newObjectsToAdd = [NSMutableSet setWithCapacity:
[objectsToAdd count]];
[newObjectsToAdd setSet:objectsToAdd];
[newObjectsToAdd minusSet:[self valueForKey:__RELATIONSHIP_NAME]];
//Dont make youself an enemy of yourself, so take self out of
the set
if ([objectsToAdd intersectsSet:[NSSet setWithObject:self]])
{
NSMutableSet *correctedObjectsToAdd = [NSMutableSet
setWithSet:objectsToAdd];
[correctedObjectsToAdd minusSet:[NSSet setWithObject:self]];
objectsToAdd = correctedObjectsToAdd;
}
[self willChangeValueForKey:__RELATIONSHIP_NAME
withSetMutation:NSKeyValueSetSetMutation usingObjects:objectsToAdd];
[[self primitiveValueForKey:__RELATIONSHIP_NAME]
setSet:objectsToAdd];
[self didChangeValueForKey:__RELATIONSHIP_NAME
withSetMutation:NSKeyValueSetSetMutation usingObjects:objectsToAdd];
//Tell any old RELATIONSHIP_NAME to take us off of thier list
NSEnumerator *oldObjectEnumerator = [oldObjectsForRemoval
objectEnumerator];
id anOldObject = nil;
while (anOldObject = [oldObjectEnumerator nextObject])
{
if (anOldObject == self)
{}
else
[[anOldObject mutableSetValueForKey:__RELATIONSHIP_NAME]
removeObject:self];
}
//Tell any new RELATIONSHIP_NAME to add us to thier list
NSEnumerator *newObjectEnumerator = [newObjectsToAdd
objectEnumerator];
id aNewObject = nil;
while (aNewObject = [newObjectEnumerator nextObject])
{
if (aNewObject == self)
{}
else
[[aNewObject mutableSetValueForKey:__RELATIONSHIP_NAME]
addObject:self];
}
}
- (void)__add_RELATED_OBJECT:(__RELATED_OBJECT_NAME *)value //could
also implement addEnemies:(NSSet *)
{
//NSLog(@"Adding enemy %@ to %@",[value valueForKey:@"name"],
[self valueForKey:@"name"]); //Object Specific Log Message
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value
count:1];
BOOL needToAddEnemy = NO;
if (value != self && ![[self valueForKey:__RELATIONSHIP_NAME]
intersectsSet:changedObjects])//Dont add yourself as __RELATIONSHIP_NAME
needToAddEnemy = YES;
[self willChangeValueForKey:__RELATIONSHIP_NAME
withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey: __RELATIONSHIP_NAME] addObject:
value];
[self didChangeValueForKey:__RELATIONSHIP_NAME
withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
if (needToAddEnemy)
[[value mutableSetValueForKey:__RELATIONSHIP_NAME]
addObject:self];
[changedObjects release];
}
- (void)__remove_RELATED_OBJECT:(__RELATED_OBJECT_NAME *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value
count:1];
BOOL needToRemoveEnemy = NO;
if (value != self && [[self valueForKey:__RELATIONSHIP_NAME]
intersectsSet:changedObjects])
needToRemoveEnemy = YES;
[self willChangeValueForKey:__RELATIONSHIP_NAME
withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey: __RELATIONSHIP_NAME] removeObject:
value];
[self didChangeValueForKey:__RELATIONSHIP_NAME
withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
if (needToRemoveEnemy)
[[value mutableSetValueForKey:__RELATIONSHIP_NAME]
removeObject:self];
[changedObjects release];
}
@end
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden