I am currently working on core data and newbie, fetching composite name and contact numbers from address book. I now can save data in to-one & to-many relationship using KVC and subclassing NSManagedObject. But still some concepts are not clear to me.

In normal DB we save data in primary & foreign key way. ID, compositeName fields in ContactName table and ID, number, type fields in ContactNumber table. Relationships can be easily created on both table ID fields.
In core data its done like this using KVC:
1. NSManagedObject *contactNameEntity = [NSEntityDescription insertNewObjectForEntityForName:@"ContactName" inManagedObjectContext:self.managedObjectContext];
2. [contactNameEntity setValue:@"TheName" forKey:@"compositeName"]
3. NSMutableSet *relationAsSet = [contactNameEntity mutableSetValueForKey:@"contactNameRelation"];
//fetching multi values like contact mobile, iPhone, home, work, other numbers and iterating them
4. ABMutableMultiValueRef multiValues = ABRecordCopyValue(ref, kABPersonPhoneProperty);
5. CFArrayRef mVArray = ABMultiValueCopyArrayOfAllValues(multiValues);
6. for(int i=0; i<CFArrayGetCount(mVArray); i++) {
7. NSManagedObject *contactNumberEntity = [NSEntityDescription insertNewObjectForEntityForName:@"ContactNumber" inManagedObjectContext:self.managedObjectContext];
8. [contactNumberEntity setValue:(__bridge NSString*)CFArrayGetValueAtIndex(mVArray, i) forKey:@"number"];
9. [contactNumberEntity setValue:(__bridge id)(ABMultiValueCopyLabelAtIndex(multiValues, i)) forKey:@"type"];
10. [relationAsSet addObject:contactNumberEntity];
}
11. [contactNameEntity setValue:relationAsSet forKey:@"contactNameRelation"];
Now with entity subclasses method #1:
1. ContactName *contactNameEntity = [NSEntityDescription insertNewObjectForEntityForName:@"ContactName" inManagedObjectContext:self.managedObjectContext];
2. [contactNameEntity setCompositeName:(__bridge id)(compositeName)];
3. for(int i=0; i<CFArrayGetCount(mVArray); i++) {
4. ContactNumber *contactNumberEntity = [NSEntityDescription
5. insertNewObjectForEntityForName:@"ContactNumber" inManagedObjectContext:self.managedObjectContext];
6. [contactNumberEntity setNumber:(__bridge NSString*)CFArrayGetValueAtIndex(mVArray, i)];
7. [contactNumberEntity setType:(__bridge id)(ABMultiValueCopyLabelAtIndex(multiValues, i))];
8. [contactNameEntity addContactNameRelationObject:contactNumberEntity];
}
Now with entity subclasses which is similar to KVC method #2:
1. ContactName *contactNameEntity = [NSEntityDescription insertNewObjectForEntityForName:@"ContactName" inManagedObjectContext:self.managedObjectContext];
2. [contactNameEntity setCompositeName:(__bridge id)(compositeName)];
3. NSSet *set = [contactNameEntity contactNameRelation];
4. NSMutableSet *mSet = [NSMutableSet setWithSet:set];
5. set = nil;
6. for(int i=0; i<CFArrayGetCount(mVArray); i++) {
7. ContactNumber *contactNumberEntity = [NSEntityDescription
8. insertNewObjectForEntityForName:@"ContactNumber" inManagedObjectContext:self.managedObjectContext];
9. [contactNumberEntity setNumber:(__bridge NSString*)CFArrayGetValueAtIndex(mVArray, i)];
10. [contactNumberEntity setType:(__bridge id)(ABMultiValueCopyLabelAtIndex(multiValues, i))];
11. [mSet addObject:contactNumberEntity];
}
12. [contactNameEntity addContactNameRelation:mSet];
Questions:
In KVC method line 3, why a normal NSSet cannot be created?
Why relationship is present as NSSet, although in normal DB relationship is just a simple thing but seems like complex in core data.
Am I using the subclass generated methods correctly or Am I using subclass generated methods in standard way? (asking to verify my concepts).
Why method #1 and method #2 differs? both are using subclasses.
Is
@property (nonatomic, retain) NSSet *contactNameRelation;andNSMutableSet *relationAsSet = [contactNameEntity mutableSetValueForKey:@"contactNameRelation"];return same object/value?
*. Please avoid any silly mistake.
*. Please tell the questions I am asking is unclear.
Edit 1
ContactName entity xcode generated subclass .h file:
@property (nonatomic, retain) NSString * number;
@property (nonatomic, retain) NSSet *contactNumbers;
@end
@interface ContactName (CoreDataGeneratedAccessors)
- (void)addContactNumbersObject:(ContactNumber *)value;
- (void)removeContactNumbersObject:(ContactNumber *)value;
- (void)addContactNumbers:(NSSet *)values;
- (void)removeContactNumbers:(NSSet *)values;
and this is .m file:
@implementation ContactName
@dynamic compositeName;
@dynamic contactNumbers;
@end
I want to know how to correctly use these methods, and thats why method 1 and 2 are two different approaches I posted above based on this subclass. Whats correct and whats not please help me out.
Edit 2
this is what I get when I log relationAsSet
$0 = 0x0854c1c0 Relationship 'contactNameRelation' on managed object (0x835bae0) <ContactName: 0x835bae0> (entity: ContactName; id: 0x835ba80 <x-coredata:///ContactName/t66752D00-F08B-40DF-AEED-ABCACEA254652> ; data: {
compositeName = myname;
contactNameRelation = (
);
}) with objects {(
)}
and this
$0 = 0x0821b460 Relationship 'contactNameRelation' on managed object (0x823fe50) <ContactName: 0x823fe50> (entity: ContactName; id: 0x823fea0 <x-coredata:///ContactName/t3CED08C3-94E0-4B43-93F0-96DE2D2A24922> ; data: {
compositeName = myname;
contactNameRelation = (
"0x821be40 <x-coredata:///ContactNumber/t3CED08C3-94E0-4B43-93F0-96DE2D2A24923>"
);
}) with objects {(
<ContactNumber: 0x8241ab0> (entity: ContactNumber; id: 0x821be40 <x-coredata:///ContactNumber/t3CED08C3-94E0-4B43-93F0-96DE2D2A24923> ; data: {
contactNumberRelation = "0x823fea0 <x-coredata:///ContactName/t3CED08C3-94E0-4B43-93F0-96DE2D2A24922>";
number = 123;
type = iphone;
})
)}
