Académique Documents
Professionnel Documents
Culture Documents
! NSManagedObject
!
!
!
!
NSPredicate
NSPredicate
!
!
NSFetchedResultsController
!
!
Collection
Employee
firstName: "Jo"
MyDocument ...
employees
departments Collection
undoManager
fileName Department
...
name: "Sales"
...
open:
save: NSUndoManager
...
file
Employee
Department
MyPersistentDocument
managedObjectContext
open:
save:
NSManagedObjectContext
Persistent
Object Store
file
Employee
Department
Fetch Request
Array
Sort Descriptor
Key:! "salary"
Ascending:! YES
Sort Descriptor
Key:! "lastName"
Ascending:! YES
managedObjectContext managedObjectContext
Customer Company
...
Persistent Persistent
Object Store Object Store
file file
Employee Customer
Department Company
NSPersistentDocument
NSDocument
NSPersistentDocument
NSPersistentDocument
NSDocument
Managed Object Model
(QWLW\'HVFULSWLRQ
1DPH (PSOR\HH
&ODVV1DPH (PSOR\HH
3URSHUWLHV $WWULEXWH'HVFULSWLRQ
1DPH ILUVW1DPH
7\SH VWULQJ
9DOXH&ODVV 166WULQJ
&ROOHFWLRQ
$WWULEXWH'HVFULSWLRQ
1DPH VDODU\
7\SH GHFLPDOQXPEHU
9DOXH&ODVV 16'HFLPDO1XPEHU
5HODWLRQVKLS'HVFULSWLRQ
1DPH GHSDUWPHQW
0D[&RXQW
'HVWLQDWLRQ(QWLW\ 'HSDUWPHQW
NSManagedObject NSManagedObject
NSManagedObject
NSManagedObject
NSManagedObjectModel
NSManagedObjectModel
NSEntityDescription
NSEntityDescription NSAttributeDescription
NSRelationshipDescription
NSFetchedPropertyDescription
NSFetchRequest
setSubentities:
NSObject
NSManagedObject
NSPropertyDescription
NSString NSDate NSNumber
0
NULL nil NULL 0
0 NULL
false == (NULL == 0)
false == (NULL != 0)
NULL
NSFetchRequest
setEntities:forConfiguration:
entitiesForConfiguration:
xcdatamodel
mom momc
NSPersistentDocument
!
mergedModelFromBundles:
! initWithContentsOfURL:
modelByMergingModels:
mergedModelFromBundles:
NSManagedObjectModel
NSPersistentDocument managedObjectModel
setFetchRequestTemplate:forName:
[model setFetchRequestTemplate:requestTemplate
forName:@"PublicationsForAuthorSinceDate"];
[requestTemplate release];
NSNull
fetchRequestFromTemplateWithName:substitutionVariables: nil
fetchRequestTemplateForName: copy
fetchRequestTemplateForName:
Can't modify a named fetch request in an immutable model
"Entity/ " " "
localizationDictionary
localizationDictionary nil
.strings .xcdatamodel
MyDocument.xcdatamodel
MyDocumentModel.strings
JimsModel.xcdatamodel
JimsModelModel.strings
"Entity/Emp" = "Employee";
"Property/firstName" = "First Name";
"Property/lastName" = "Last Name";
"Property/salary" = "Salary";
NSManagedObjectModel
setLocalizationDictionary:
[runEntity setProperties:runProperties];
NSManagedObject NSManagedObject
NSManagedObject
NSManagedObject
NSEntityDescription
NSManagedObject
NSEntityDescription
NSManagedObject
NSAttributeDescription
NSManagedObject
NSAttributeDescription NSManagedObject
NSColor NSRect
NSManagedObject
NSManagedObject NSDate
NSTimeInterval
NSManagedObject
NSManagedObject
NSManagedObject
NSManagedObject NSObject
NSManagedObject
primitiveValueForKey:
setPrimitiveValue:forKey: isEqual: hash superclass class self zone isProxy
isKindOfClass: isMemberOfClass: conformsToProtocol: respondsToSelector: retain
release autorelease retainCount managedObjectContext entity objectID isInserted
isUpdated isDeleted isFault description
initWithEntity:insertIntoManagedObjectContext:
valueForKey: setValue:forKeyPath:
awakeFromInsert awakeFromFetch
validateForUpdate:
@interface MyManagedObject : NSManagedObject {
}
@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSDate *date;
@end
nonatomic retain
NSCopying
dynamic
@implementation MyManagedObject
@dynamic title;
@dynamic date;
@end
dealloc
init
NSManagedObject
initWithEntity:insertIntoManagedObjectContext: awakeFromInsert awakeFromFetch
init
initWithEntity:insertIntoManagedObjectContext:
awakeFromInsert
awakeFromFetch
! awakeFromInsert
awakeFromInsert
initWithEntity:insertIntoManagedObjectContext:
insertNewObjectForEntityForName:inManagedObjectContext: awakeFromInsert
- (void) awakeFromInsert
{
[super awakeFromInsert];
[self setCreationDate:[NSDate date]];
}
! awakeFromFetch
awakeFromFetch
awakeFromFetch
awakeFromInsert
performSelector:withObject:afterDelay:
dealloc finalize
didTurnIntoFault didTurnIntoFault
didTurnIntoFault
NSManagedObject
validateValue:forKey:error:
validate<Key>:error: NSKeyValueCoding
validateForUpdate:
validateValue:forKey:error:
validateValue:forKey:error:
validateValue:forKey:error:
validateForUpdate:
NSDetailedErrorsKey NSError
description description
description
valueForKey:
NSManagedObject
!
willAccessValueForKey: didAccessValueForKey: willChangeValueForKey:
didChangeValueForKey: willChangeValueForKey:withSetMutation:usingObjects:
didChangeValueForKey:withSetMutation:usingObjects:
NSManagedObject
!
NSObject valueForKey:
valueForKey:
NSManagedObject
primitive
NSManagedObject
valueForKey:
add<Key>Object: remove<Key>s:
mutableSetValueForKey:
firstName firstName
setFirstName: primitiveFirstName setPrimitiveFirstName:
NSManagedObject
(nonatomic, retain)
nonatomic
copy
NSSet *
NSManagedObject
- (void)addDirectReportsObject:(Employee *)value;
- (void)removeDirectReportsObject:(Employee *)value;
- (void)addDirectReports:(NSSet *)value;
- (void)removeDirectReports:(NSSet *)value;
@end
NSCopying copy
@dynamic
@dynamic
@implementation Parent
@dynamic parentString;
@end
@implementation Child
- (NSString *)parentString
{
// this throws a "selector not found" exception
return parentString.foo;
}
@end
@dynamic
NSManagedObject
@dynamic name;
- (NSString *)name
{
[self willAccessValueForKey:@"name"];
NSString *myName = [self primitiveName];
[self didAccessValueForKey:@"name"];
return myName;
}
- (void)setName:(NSString *)newName
{
[self willChangeValueForKey:@"name"];
[self setPrimitiveName:newName];
[self didChangeValueForKey:@"name"];
}
@end
NSCopying NSString
NSMutableString
@implementation Department
@dynamic name;
- (void)setName:(NSString *)newName
{
[self willChangeValueForKey:@"name"];
// NSString implements NSCopying, so copy the attribute value
NSString *newNameCopy = [newName copy];
[self setPrimitiveName:newNameCopy];
[newNameCopy release];
[self didChangeValueForKey:@"name"];
}
@end
NSInteger CGFloat
NSKeyValueCoding NSRect NSPoint NSSize NSRange
@interface Circle : NSManagedObject
{
CGFloat radius;
}
@property CGFloat radius;
@end
@implementation Circle
- (CGFloat)radius
{
[self willAccessValueForKey:@"radius"];
float f = radius;
[self didAccessValueForKey:@"radius"];
return f;
}
- (void)setRadius:(CGFloat)newRadius
{
[self willChangeValueForKey:@"radius"];
radius = newRadius;
[self didChangeValueForKey:@"radius"];
}
@end
@dynamic
mutableSetValueForKey:
add<Key>Object:
remove<Key>Object:
employees
- (void)addEmployeesObject:(Employee *)value;
- (void)removeEmployeesObject:(Employee *)value;
- (void)addEmployees:(NSSet *)value;
- (void)removeEmployees:(NSSet *)value;
- (NSMutableSet*)primitiveEmployees;
- (void)setPrimitiveEmployees:(NSMutableSet*)value;
@end
@implementation Department
@dynamic name;
@dynamic employees;
- (void)addEmployeesObject:(Employee *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"employees"
withSetMutation:NSKeyValueUnionSetMutation
usingObjects:changedObjects];
[[self primitiveEmployees] addObject:value];
[self didChangeValueForKey:@"employees"
withSetMutation:NSKeyValueUnionSetMutation
usingObjects:changedObjects];
[changedObjects release];
}
- (void)removeEmployeesObject:(Employee *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"employees"
withSetMutation:NSKeyValueMinusSetMutation
usingObjects:changedObjects];
[[self primitiveEmployees] removeObject:value];
[self didChangeValueForKey:@"employees"
withSetMutation:NSKeyValueMinusSetMutation
usingObjects:changedObjects];
[changedObjects release];
}
- (void)addEmployees:(NSSet *)value
{
[self willChangeValueForKey:@"employees"
withSetMutation:NSKeyValueUnionSetMutation
usingObjects:value];
[[self primitiveEmployees] unionSet:value];
[self didChangeValueForKey:@"employees"
withSetMutation:NSKeyValueUnionSetMutation
usingObjects:value];
}
- (void)removeEmployees:(NSSet *)value
{
[self willChangeValueForKey:@"employees"
withSetMutation:NSKeyValueMinusSetMutation
usingObjects:value];
[[self primitiveEmployees] minusSet:value];
[self didChangeValueForKey:@"employees"
withSetMutation:NSKeyValueMinusSetMutation
usingObjects:value];
}
primitiveValueForKey:
setPrimitiveValue:forKey: valueForKey:
setValue:forKey:
int16 Integer
16 nonCompliantKVCivar
alloc
! NSManagedObject NSManagedObject
insertNewObjectForEntityForName:inManagedObjectContext: NSEntityDescription
init
NSManagedObject
initWithEntity:insertIntoManagedObjectContext:
save:
NSEntityDescription
NSPersistentDocument
managedObjectContext
NSManagedObject
entityForName:inManagedObjectContext:
NSEntityDescription
NSManagedObject
alloc
NSManagedObject
init
initWithEntity:insertIntoManagedObjectContext:
NSEntityDescription
insertNewObjectForEntityForName:inManagedObjectContext:
insertNewObjectForEntityForName:inManagedObjectContext:
NSManagedObject
initWithEntity:insertIntoManagedObjectContext:
initWithEntity:insertIntoManagedObjectContext:
Employee Employee
NSManagedObject NSManagedObject
NSManagedObject
alloc
Employee
Employee
NSManagedObject NSManagedObject
NSManagedObject
init
initWithEntity:insertIntoManagedObjectContext:
NSManagedObject
NSEntityDescription
insertNewObjectForEntityForName:inManagedObjectContext:
insertNewObjectForEntityForName:inManagedObjectContext:
NSManagedObject
initWithEntity:insertIntoManagedObjectContext:
NSManagedObjectContext
assignObject:toPersistentStore:
persistentStoreForURL:
deleteObject:
[aContext deleteObject:aManagedObject];
isDeleted
YES
deleteObject:
NSManagedObjectContextObjectsDidChangeNotification
NSManagedObjectContext deletedObjects
NSManagedObjectContextDidSaveNotification
NSExpressionDescription
NSEntityDescription entityForName:inManagedObjectContext:
executeFetchRequest:error:
NSError *error;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil)
{
// Deal with error...
}
NSArrayController
self == %@
NSPredicate *predicate =
[NSPredicate predicateWithFormat:@"self == %@", targetObject];
[request setPredicate:predicate];
NSError *error;
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
if (array != nil) {
int count = [array count]; // may be 0 if the object has been deleted
// …
}
else // deal with error…
0
IN
NSExpressionDescription
setResultType: NSDictionaryResultType
! NSExpressionDescription
NSExpression
max: min:
expressionForFunction:arguments:
executeFetchRequest:error:
// The name is the key that will be used in the dictionary for the return value.
[expressionDescription setName:@"minDate"];
[expressionDescription setExpression:minExpression];
[expressionDescription setExpressionResultType:NSDateAttributeType];
// Set the request's properties to fetch just the property represented by the
expressions.
[request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];
[expressionDescription release];
[request release];
NSString *firstName = [anEmployee firstName];
Employee *manager = anEmployee.manager;
newEmployee.firstName = @"Stig";
[newEmployee setManager:manager];
firstName (copy)
setFirstName:
setString: firstName
NSManagedObject
hasFaultForRelationshipNamed:
mutableSetValueForKey:
// or
[aDepartment addEmployeesObject:newEmployee];
[aDepartment removeEmployeesObject:firedEmployee];
mutableSetValueForKey: mutableSetValueForKey:
save:
NSManagedObjectID
managedObjectIDForURIRepresentation: objectWithID:
pasteboard:provideDataForType:
addTypes:owner: pasteboard:provideDataForType:
validate<Key>:error:
undo redo
rollback
reset
beginUndoGrouping endUndoGrouping
processPendingChanges
disableUndoRegistration
enableUndoRegistration processPendingChanges
NSManagedObjectContext refreshObject:mergeChanges:
manager department
NSString *managersName =
[[anEmployee valueForKey:@"manager"] valueForKey:@"lastName];
NSString *managersName =
[anEmployee valueForKeyPath:@"manager.lastName"];
firstName lastName
fullName fullName
fullName
awakeFromFetch
! firstName
fullName
! lastName
fullName
mergeChanges YES
" firstName
" lastName
" fullName
awakeFromFetch
awakeFromFetch
fullNameIsValid BOOL
didTurnIntoFault NO
fullName fullNameIsValid NO
NSEntityDescription
insertNewObjectForEntityForName:inManagedObjectContext:
NSArrayController
nil
release
refreshObject:mergeChanges:
refreshObject:mergeChanges:
mergeChanges YES
NO
nil
@interface Widget : NSObject
{
Sprocket *sprocket;
}
init
1
Before After
Employee Employee
department department
anEmployee.department = newDepartment;
directReports
employees
cousins
friends
befriendedBy
source friend
source friend
! friend
friends
source befriendedBy
employee
employee
department employee
id x = [employee department];
x nil
employee
[managedObjectContext deleteObject:department];
refreshObject:mergeChanges:
$FETCH_SOURCE
$FETCHED_PROPERTY
university.name LIKE [c]
$FETCH_SOURCE.searchTerm $FETCHED_PROPERTY
NSAttributeDescription
NSValueTransformer
NSData
NSKeyedUnarchiveFromDataTransformerName
NSData
NSKeyedUnarchiveFromDataTransformerName
! setAttributeType:
NSTransformableAttributeType
setValueTransformerName:
favoriteColor
@end
@implementation Person
@dynamic firstName;
@dynamic lastName;
@dynamic favoriteColor;
@end
Employee *newEmployee =
[NSEntityDescription insertNewObjectForEntityForName:@"Employee"
inManagedObjectContext:myManagedObjectContext];
newEmployee.firstName = @"Captain";
newEmployee.lastName = @"Scarlet";
newEmployee.favoriteColor = [NSColor redColor];
NSColor
NSUndefinedAttributeType
NSPoint NSSize
NSRect NSRange
NSValue
NSValue
NSValue
NSData
NSValue NSCoding
NSRect
NSRectFromString
nil
nil
- (NSColor *)color
{
[self willAccessValueForKey:@"color"];
NSColor *color = [self primitiveColor];
[self didAccessValueForKey:@"color"];
if (color == nil)
{
NSData *colorData = [self colorData];
if (colorData != nil)
{
color = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];
[self setPrimitiveColor:color];
}
}
return color;
}
awakeFromFetch
- (void)awakeFromFetch
{
[super awakeFromFetch];
NSData *colorData = [self colorData];
if (colorData != nil)
{
NSColor *color;
color = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];
[self setPrimitiveColor:color];
}
}
- (NSColor *)color
{
[self willAccessValueForKey:@"color"];
NSColor *color = [self primitiveColor];
[self didAccessValueForKey:@"color"];
return color;
}
- (void)setColor:(NSColor *)aColor
{
[self willChangeValueForKey:@"color"];
[self setPrimitiveValue:aColor forKey:@"color"];
[self didChangeValueForKey:@"color"];
[self setValue:[NSKeyedArchiver archivedDataWithRootObject:aColor]
forKey:@"colorData"];
}
willSave
- (void)setColor:(NSColor *)aColor
{
[self willChangeValueForKey:@"color"];
[self setPrimitiveValue:aColor forKey:@"color"];
[self didChangeValueForKey:@"color"];
}
- (void)willSave
{
NSColor *color = [self primitiveValueForKey:@"color"];
if (color != nil)
{
[self setPrimitiveValue:[NSKeyedArchiver archivedDataWithRootObject:color]
forKey:@"colorData"];
}
else
{
[self setPrimitiveValue:nil forKey:@"colorData"];
}
[super willSave];
}
colorData nil
colorData nil validateForUpdate:
willSave colorData nil
primitiveLength
setPrimitiveLength:
! NSNumber
!
length
double NSDoubleAttributeType length
primitiveLength setPrimitiveLength:
- (double)length
{
[self willAccessValueForKey:@"length"];
NSNumber *tmpValue = [self primitiveLength];
[self didAccessValueForKey:@"length"];
return (tmpValue!=nil) ? [tmpValue doubleValue] : 0.0; // Or a suitable
representation for nil.
}
- (void)setLength:(double)value
{
NSNumber* temp = [[NSNumber alloc] initWithDouble: value];
[self willChangeValueForKey:@"length"];
[self setPrimitiveLength:temp];
[self didChangeValueForKey:@"length"];
[temp release];
}
NSPoint NSSize
NSRect NSRange
bounds NSRect
- (NSRect)primitiveBounds
{
return myBounds;
}
- (void)setPrimitiveBounds:(NSRect)aRect
myBounds = aRect;
}
nil
0 0
- (NSRect)bounds
{
[self willAccessValueForKey:@"bounds"];
NSRect aRect = bounds;
[self didAccessValueForKey:@"bounds"];
if (aRect.size.width == 0)
{
NSString *boundsAsString = [self boundsAsString];
if (boundsAsString != nil)
{
bounds = NSRectFromString(boundsAsString);
}
}
return bounds;
}
- (void)setBounds:(NSRect)aRect
{
[self willChangeValueForKey:@"bounds"];
bounds = aRect;
[self didChangeValueForKey:@"bounds"];
NSString *rectAsString = NSStringFromRect(aRect);
[self setValue:rectAsString forKey:@"boundsAsString"]; }
setAttributeValueClassName:
NSPersistentDocument
favoriteColor MyColor
NSColor
- (NSManagedObjectModel *)managedObjectModel
{
if (myManagedObjectModel == nil)
{
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *path = [bundle pathForResource:@"MyDocument" ofType:@"mom"];
NSURL *url = [NSURL fileURLWithPath:path];
myManagedObjectModel = [[NSManagedObjectModel alloc]
initWithContentsOfURL:url];
NSEntityDescription *employeeEntity =
[[myManagedObjectModel entitiesByName] objectForKey:@"Employee"];
NSAttributeDescription *favoriteColorAttribute =
[[employeeEntity attributesByName] objectForKey:@"favoriteColor"];
return myManagedObjectModel;
}
- (void)windowControllerDidLoadNib:(NSWindowController *)windowController
{
[super windowControllerDidLoadNib:windowController];
Employee *newEmployee =
[NSEntityDescription insertNewObjectForEntityForName:@"Employee"
inManagedObjectContext:[self managedObjectContext]];
newEmployee.firstName = @"Captain";
newEmployee.lastName = @"Scarlet";
newEmployee.favoriteColor = [NSColor redColor]; // exception thrown here
}
MyColour MyColor
NSKeyValueCoding
NSKeyValueCoding validateValue:forKey:error:
valueForKey:
validateValue:forKey:error:
validate<Key>:error:
validateValue:forKey:error:
NO null NSError
id *
validateValue:forKey:error:
validateValue:forKey:error:
validate<Key>:error:
willSave
12
age YES hasDrivingLicense
NSManagedObject
validateFor… validateForUpdate:
NO
0 0
birthday hasDrivingLicense
validateForInsert:
validateForUpdate:
- (BOOL)validateForInsert:(NSError **)error
{
BOOL propertiesValid = [super validateForInsert:error];
// could stop here if invalid
BOOL consistencyValid = [self validateConsistency:error];
return (propertiesValid && consistencyValid);
}
- (BOOL)validateForUpdate:(NSError **)error
{
BOOL propertiesValid = [super validateForUpdate:error];
// could stop here if invalid
BOOL consistencyValid = [self validateConsistency:error];
return (propertiesValid && consistencyValid);
}
- (BOOL)validateConsistency:(NSError **)error
{
static NSCalendar *gregorianCalendar;
if (gregorianCalendar == nil) {
gregorianCalendar = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
}
NSDateComponents *components = [gregorianCalendar
components:NSYearCalendarUnit
fromDate:myBirthday
toDate:[NSDate
date]
options:0];
int years = [components year];
valid = NO;
code:NSManagedObjectValidationError
userInfo:userInfo];
NSError
Employee
firstName: "Toni"
lastName: "Lau" Department
salary: 7000
name:
manager department budget:
department
reports employees
isFault isFault NO
isFault YES
nil
refreshObject:mergeChanges:
NO mergeChanges
didTurnIntoFault
didTurnIntoFault
vm_deallocate munmap sbrk
Employee
firstName: "Toni"
lastName: "Lau" Department
salary: 7000
name:
manager department budget:
department
reports employees
Employee
firstName: "Jo"
lastName: "Jackson" Department
salary: 5000
name:
manager department budget:
department
reports nil employees
Employee
firstName: "Toni"
lastName: "Lau"
salary: 7000
manager
department department
Department
reports
name:
budget:
Employee
employees
firstName: "Jo" department
lastName: "Jackson"
salary: 5000
manager
department
reports nil
NSPersistentStoreCoordinator
NSPersistentStore
NSPersistentStore *roStore =
[psc addPersistentStoreWithType:NSXMLStoreType
configuration:nil URL:url
options:options error:&error];
persistentStoreForURL:
NSPersistentStoreCoordinator
migratePersistentStore:toURL:options:withType:error:
NSPersistentStoreCoordinator *psc = [aManagedObjectContext persistentStoreCoordinator];
NSURL *oldURL, *newURL; // define URLs...
NSError *error;
NSPersistentStore *xmlStore = [psc persistentStoreForURL:oldURL];
NSPersistentStore *sqLiteStore = [psc migratePersistentStore:xmlStore
toURL:newURL
options:nil
withType:NSSQLiteStoreType
error:&error];
addPersistentStore:
removePersistentStore:
NSPersistentStoreCoordinator
metadataForPersistentStoreWithURL:error:
NSPersistentStore metadataForPersistentStoreWithURL:error:
NSPersistentStore
setMetadata:forPersistentStoreWithURL:error:
kMDItemKeywords
NSStoreType NSStoreUUID
NSError *error;
NSURL *storeURL = /* URL for persistent store */ ;
NSDictionary *metadata =
[NSPersistentStore metadataForPersistentStoreWithURL:storeURL error:&error]
if (metadata == nil)
{
/* deal with the error */
}
else
{
NSMutableDictionary *newMetadata =
[[metadata mutableCopy] autorelease];
[newMetadata setObject:[NSArray arrayWithObject:@"MyKeyWord"]
forKey:(NSString *)kMDItemKeywords];
// set additional key-value pairs as appropriate
[NSPersistentStore setMetadata:newMetadata
forPersistentStoreWithURL:storeURL
error:&error];
}
NSPersistentStoreCoordinator setMetadata:forPersistentStore:
pStore nil
if (pStore != nil) {
NSMutableDictionary *metadata =
[[[psc metadataForPersistentStore:pStore] mutableCopy] autorelease];
[metadata setObject:[NSArray arrayWithObject:@"MyKeyWord"]
forKey:(NSString *)kMDItemKeywords];
// set additional key-value pairs
[psc setMetadata:metadata forPersistentStore:pStore];
}
URIRepresentation
!
NSObjectController NSArrayController
!
!
setAutomaticallyPreparesContent:
awakeFromNib windowControllerDidLoadNib:
nil
fetchWithRequest:merge:error: nil
- (void)windowControllerDidLoadNib:(NSWindowController *) windowController
{
[super windowControllerDidLoadNib:windowController];
NSError *error;
BOOL ok = [arrayController fetchWithRequest:nil merge:NO error:&error];
// ...
ANY ALL
ANY
NSArrayController NSArrayController
arrangeObjects: super
Managed Object Context 1 Managed Object Context 1
manager manager
Employee Employee
File
Employee Employee
lastName: "Lau" lastName: "Jackson"
salary: 8000 salary: 4500
manager
Employee
lastName: "Weiss"
salary: 8000
!
!
NSErrorMergePolicy
userInfo
@"conflictList"
NSErrorMergePolicy
NSMergeByPropertyStoreTrumpMergePolicy
NSMergeByPropertyObjectTrumpMergePolicy NSOverwriteMergePolicy
NSRollbackMergePolicy
moc1 moc2
moc1 NSManagedObjectContextDidSave
moc2
moc2
moc2 reset
objectID
IN
moc2
moc1 moc2
moc2
moc2
NSMergePolicyOverwrite
moc2 moc1
moc2
NSMergePolicyOverwrite
moc1
moc2
id
NSPersistentStore * id
NSBinaryStoreType
insertObject: assignObject:toPersistentStore:
NSManagedObjectContextDidSaveNotification
NSString
compare:
caseInsensitiveCompare: localizedCompare: localizedCaseInsensitiveCompare:
localizedStandardCompare:
! MATCHES
MATCHES
!
toOne.toMany.toMany toMany.toOne.toMany
ALL ANY IN
fsync
F_FULLFSYNC
! synchronous
! full_fsync
PRAGMA fullfsync 1 / 0
NSSQLitePragmasOption
NSSQLitePragmasOption
NSDictionary *storeOptions =
[NSDictionary dictionaryWithObject:pragmaOptions
forKey:NSSQLitePragmasOption];
NSPersistentStore *store;
NSError *error;
store = [psc addPersistentStoreWithType:NSSQLiteStoreType
configuration: nil
URL:url
options:storeOptions
error:&error];
full_fsync fsync
F_FULLFSYNC
com.apple.CoreData.SQLiteDebugSynchronous
0
1
2 fctl FULL_FSYNC
FULL_FSYNC
!
NSLocking
objectWithID:
NSFetchRequest
! executeFetchRequest:error:
!
NSLocking
tryLock lock
objectWithID:
NSThread
pthread
NSManagedObject
NSManagedObject
contains endsWith like matches
setFetchLimit:
fetchOffset
isEqual hash
valueForKey:
description
description
isFault
Department Employee
IN
self
NSArray *array = [NSArray arrayWithObjects:fault1, fault2, ..., nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self IN %@", array];
NSFetchRequest
setReturnsObjectsAsFaults:
NSFetchRequest
setRelationshipKeyPathsForPrefetching:
! @"%K IN %@"
!
@"SELF IN %@"
! NSManagedObjectContext
refreshObject:mergeChanges:
nil
! includesPropertyValues NO
! reset NSManagedObjectContext
!
nil
refreshObject:mergeChanges:
NSManagedObjectContext
com.apple.CoreData.SQLDebug
stderr
-com.apple.CoreData.SQLDebug 1
!
executeFetchRequest:error:
save:
!
"Could not merge changes"
committedValuesForKeys:
refreshObject:mergeChanges:
!
<NSObjectInaccessibleException> [<MyMO 0x3036b0>_assignObject:toPersistentStore:]:
The NSManagedObject with ID:#### has been invalidated.
reset
init
initWithEntity:inManagedObjectContext:
NSManagedObject initWithEntity:insertIntoManagedObjectContext:
NSManagedObject
NSManagedObject *entityInstance =
[NSEntityDescription insertNewObjectForEntityForName:@"MyEntity"
inManagedObjectContext:managedObjectContext];
[entityInstance setAttribute: newValue];
NSManagedObject
NSString
NSArrayController
Exception raised during posting of notification. Ignored. exception: Cannot
perform operation since entity with name 'Wxyz' cannot be found
NSObjectController
-[NSSQLCore retainedDataForObjectID:withContext:]
_conflictsWithRowCacheForObject:
objectWithID:
!
! refreshObject:
! NSManagedObject
updatedObjects deletedObjects
NO isTemporaryID
com.apple.CoreData.SQLDebug
stderr
-com.apple.CoreData.SQLDebug 1
nil
! nil
!
setPersistentStoreCoordinator:
NSPersistentDocument
mergedModelFromBundles:
NSPersistentDocument
contentSet NSArrayController
self contentSet
.selection.employees
.selection.self.employees
NSObjectController NSArrayController NSTreeController
nil
awakeFromNib
windowControllerDidLoadNib:
fetchWithRequest:merge:error:
NSArrayController
add:
NSManagedObject
contentArray
contentSet
contentSet
contentSet
[Department Controller].selection.employees
automaticallyPreparesContent
alloc init release
// before loop
NSString *predicateString = [NSString stringWithFormat
@"employeeID == $EMPLOYEE_ID"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
nil
save:
count++;
if (count == LOOP_LIMIT) {
[importContext save:outError];
[importContext reset];
[pool drain];
pool = [[NSAutoreleasePool alloc] init];
count = 0;
}
}
// Save any remaining records
if (count != 0) {
[importContext save:outError];
[importContext reset];
}
[pool drain];
NSDocumentController
openURLForReadingLegacyData:error: nextRecord
closeLegacyFile
@implementation MyDocumentController
- (id)openDocumentWithContentsOfURL:(NSURL *)absoluteURL
display:(BOOL)displayDocument error:(NSError **)outError {
if ([type isEqualToString:CORE_DATA_DOCUMENT_TYPE]) {
return [super openDocumentWithContentsOfURL:absoluteURL
display:displayDocument error:outError];
}
[newMO release];
count++;
if (count == LOOP_LIMIT) {
ok = [importContext save:outError];
if (!ok) {
[importContext release];
[pool drain];
[self closeLegacyFile];
return nil;
}
/*
reset is not actually needed in this example since we're not creating
any relationships but this would be one place to put it if we were
[importContext reset];
or:
for (NSManagedObject* mo in [importContext registeredObjects]) {
[importContext refreshObject:mo mergeChanges:NO];
}
*/
[pool drain];
if (!ok) {
return nil;
}
return [super openDocumentWithContentsOfURL:storeURL
display:displayDocument error:outError];
}
O(n) O(n^2)
IN
IN
name
listOfIDsAsString
IN
IN IN
// create the fetch request to get all Employees matching the IDs
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity:
[NSEntityDescription entityForName:@"Employee"
inManagedObjectContext:aMOC]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"(employeeID IN
%@)", employeeIDs]];
NSError *error;
NSArray *employeesMatchingNames = [aMOC
executeFetchRequest:fetchRequest error:&error];
// get the names to parse in sorted order
NSArray *employeeIDs = [[listOfIDsAsString componentsSeparatedByString:@"\n"]
sortedArrayUsingSelector: @selector(compare:)];
// create the fetch request to get all Employees matching the IDs
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity:
[NSEntityDescription entityForName:@"Employee"
inManagedObjectContext:aMOC]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"(employeeID IN
%@)", employeeIDs]];
managedObjectContext
NSController
NSArrayController
keyPathsForValuesAffectingValueForKey:
keyPathsForValuesAffectingValueForKey:
if ([key isEqualToString:@"fullNameAndDepartment"])
{
NSSet *affectingKeys = [NSSet setWithObjects:@"lastName", @"firstName",
@"department.deptName",
nil];
keyPaths = [keyPaths setByAddingObjectsFromSet:affectingKeys];
}
return keyPaths;
}
keyPathsForValuesAffectingFullNameAndDepartment
+ (NSSet *)keyPathsForValuesAffectingFullNameAndDepartment
{
return [NSSet setWithObjects:@"lastName", @"firstName",
@"department.deptName", nil];
}
setKeys:triggerChangeNotificationsForDependentKey:
keyPathsForValuesAffectingValueForKey:
employees salary
totalSalary
keyPathsForValuesAffectingTotalSalary
employees.salary
observeValueForKeyPath:ofObject:change:context:
NSDocument
windowWillReturnUndoManager:
windowWillReturnUndoManager:
NSObjectController NSArrayController
contentSet
save:
YES NSNumber
NSValidatesImmediatelyBindingOption
NSManagedObject
!
initWithType:error:
metadataForPersistentStoreWithURL:error:
EOModelGroup NSManagedObjectModel
setRelationshipKeyPathsForPrefetching:
! NSManagedObject EOGenericRecord
! NSManagedObjectContext EOEditingContext
! NSManagedObjectModel EOModel
! NSPersistentStoreCoordinator EOObjectStoreCoordinator
awakeFromInsert
SELECT
NSFetchRequest NSManagedObject
NSManagedObject
NSPredicate
NSManagedObjectContext
NSManagedObjectContext
NSManagedObjectModel
NSManagedObjectModel
WHERE
UPDATE WHERE
NSPersistentStoreCoordinator
willAccessValueForKey:
didChangeValueForKey: