reference: http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html#//apple_ref/doc/uid/TP30001200-SW1
Why Should You Use Core Data?
50% to 70% smaller as measured by lines of code
50% to 70% smaller as measured by lines of code
Core Data has a mature code base whose quality is maintained
Core Data integrates well with the OS X tool chain
What Core Data Is Not
Core Data is not a relational database or a relational database management system (RDBMS).
Core Data is not a relational database or a relational database management system (RDBMS).
Core Data is not a silver bullet.
Core Data does not rely on Cocoa bindings.
Core Data does not rely on Cocoa bindings.
Basic Core Data Architecture
[idAttribute setValidationPredicates:@[validationPredicate]
Managed Objects and Contexts
You can think of a managed object context as an intelligent scratch pad. When you fetch objects from a persistent store, you bring temporary copies onto the scratch pad where they form an object graph (or a collection of object graphs). You can then modify those objects however you like. Unless you actually save those changes, however, the persistent store remains unaltered.
You can think of a managed object context as an intelligent scratch pad. When you fetch objects from a persistent store, you bring temporary copies onto the scratch pad where they form an object graph (or a collection of object graphs). You can then modify those objects however you like. Unless you actually save those changes, however, the persistent store remains unaltered.
Model objects that tie into in the Core Data framework are known as managed objects. All managed objects
must be registered with a managed object context.
To retrieve data using a managed object context, you create a fetch request. A fetch request is an object that
specifies what data you want, for example, “all Employees,” or “all Employees in the Marketing department
ordered by salary, highest to lowest.”
Fetch Requests
Persistent Store Coordinator
Between managed object contexts and persistent object stores there is a persistent store coordinator.
Between managed object contexts and persistent object stores there is a persistent store coordinator.
Persistent Documents
The NSPersistentDocument class is a subclass of NSDocument that is designed to let you easily take advantage of the Core Data framework. By default, an NSPersistentDocument instance creates its own ready-to-use persistence stack, including a managed object context and a single persistent object store. There is in this case a one-to-one mapping between a document and an external data store.
The NSPersistentDocument class is a subclass of NSDocument that is designed to let you easily take advantage of the Core Data framework. By default, an NSPersistentDocument instance creates its own ready-to-use persistence stack, including a managed object context and a single persistent object store. There is in this case a one-to-one mapping between a document and an external data store.
Managed Objects and the Managed Object Model
A managed object model is a schema that provides a description of the managed objects, or entities, used by your application
A managed object model is a schema that provides a description of the managed objects, or entities, used by your application
Managed objects must be instances of either NSManagedObject or of a subclass of NSManagedObject.
NSManagedObject is able to represent any entity.
Managed Object Models
he schema is represented by a managed object model—an instance of NSManagedObjectModel. In general, the richer the model, the better Core Data is able to support your application.
Managed Object Models
he schema is represented by a managed object model—an instance of NSManagedObjectModel. In general, the richer the model, the better Core Data is able to support your application.
Features of a Managed Object Model
A managed object model is an instance of the NSManagedObjectModel class
Entities
A model contains NSEntityDescription objects that represent the model's entities. Two important features of an entity are its name, and the name of the class used to represent the entity at runtime.
Entities
A model contains NSEntityDescription objects that represent the model's entities. Two important features of an entity are its name, and the name of the class used to represent the entity at runtime.
Entity Inheritance
A property
name cannot be the same as any no-parameter method name of NSObject or NSManagedObject—for
example, you cannot give a property the name “description” (see NSPropertyDescription).
Abstract Entities
You can specify that an entity is abstract—that is, that you will not create any instances of that entity. You typically make an entity abstract if you have a number of entities that all represent specializations of (inherit from) a common entity which should not itself be instantiated
You can specify that an entity is abstract—that is, that you will not create any instances of that entity. You typically make an entity abstract if you have a number of entities that all represent specializations of (inherit from) a common entity which should not itself be instantiated
Properties
An entity's properties are its attributes and relationships, including its fetched properties (if it has any).
An entity's properties are its attributes and relationships, including its fetched properties (if it has any).
Attributes
Core Data natively supports a variety of attribute types, such as string, date, and integer (represented as instances of NSString, NSDate, and NSNumber respectively).
You can specify that an attribute is optional—that is, it is not required to have a value. In general, however, you are discouraged from doing so—especially for numeric values (typically you can get better results using a mandatory attribute with a default value—in the model—of 0). The reason for this is that SQL has special comparison behavior for NULL that is unlike Objective-C's nil. NULL in a database is not the same as 0, and searches for 0 will not match columns with NULL.
Core Data natively supports a variety of attribute types, such as string, date, and integer (represented as instances of NSString, NSDate, and NSNumber respectively).
You can specify that an attribute is optional—that is, it is not required to have a value. In general, however, you are discouraged from doing so—especially for numeric values (typically you can get better results using a mandatory attribute with a default value—in the model—of 0). The reason for this is that SQL has special comparison behavior for NULL that is unlike Objective-C's nil. NULL in a database is not the same as 0, and searches for 0 will not match columns with NULL.
Relationships
Core Data supports to-one and to-many relationships, and fetched properties. Fetched properties represent weak, one-way relationships. I
Core Data supports to-one and to-many relationships, and fetched properties. Fetched properties represent weak, one-way relationships. I
Fetch Request Templates
You use the NSFetchRequest class to describe fetch requests to retrieve objects from a persistent store. It is often the case that you want to execute the same request on multiple occasions, or execute requests that follow a given pattern but which contain variable elements (typically supplied by the user). For example, you might want to be able to retrieve all publications written by a certain author, perhaps after a date specified by the user at runtime.
You can predefine fetch requests and store them in a managed object model as named templates. This allows you to pre-define queries that you can retrieve as necessary from the model. Typically, you define fetch request templates using the Xcode data modeling tool (see Xcode Tools for Core Data ). The template may include variables, as shown in Figure 2.
You use the NSFetchRequest class to describe fetch requests to retrieve objects from a persistent store. It is often the case that you want to execute the same request on multiple occasions, or execute requests that follow a given pattern but which contain variable elements (typically supplied by the user). For example, you might want to be able to retrieve all publications written by a certain author, perhaps after a date specified by the user at runtime.
You can predefine fetch requests and store them in a managed object model as named templates. This allows you to pre-define queries that you can retrieve as necessary from the model. Typically, you define fetch request templates using the Xcode data modeling tool (see Xcode Tools for Core Data ). The template may include variables, as shown in Figure 2.
Configurations
A configuration has a name and an associated set of entities.
You typically use configurations if you want to store different entities in different stores. A persistent store
coordinator can only have one managed object model, so by default each store associated with a given
coordinator must contain the same entities.
Using a Managed Object Model
Managed Object Model means abc.xcdatamodeld
Compiling a Data Model
The model file is compiled using the model compiler, momc,
to remove the extraneous information and make runtime loading of the resource as efficient as possible. An
xcdatamodeld “source” directory is compiled into a momd deployment directory, and an xcdatamodel
“source” file is compiled into a mom deployment file.
Creating and Loading a Managed Object Model
Managed Object Model means abc.xcdatamodeld
Compiling a Data Model
momc is located in /Developer/usr/bin/. If you want to use it in your own build scripts, its usage is momc
source destination, where source is the path of the Core Data model to compile and destination is
the path of the output.
Loading a Data Model
If you want to load a model yourself, there are two mechanisms you can use:
1.You can load a single model from a specific URL, using the instance method initWithContentsOfURL:.
2. You can create a merged model from a specific collection of bundles, using the class method mergedModelFromBundles:.
1.You can load a single model from a specific URL, using the instance method initWithContentsOfURL:.
2. You can create a merged model from a specific collection of bundles, using the class method mergedModelFromBundles:.
Problems May Arise if Your Project Contains More Than One Model
If you simply rename your model file, Core Data attempts to merge the current and the old versions and
you get an error similar to the following:
reason = "'Can't merge models with two different entities named
'EntityName''";
If you create a new model that contains different entities from those in your original model, then Core
Data merges the old and new models. If you have an existing store, you get an error similar to the following
when you attempt to open it:
reason = "The model used to open the store is incompatible with the one
used to create the store";
There are two solutions:
2. Instead of mergedModelFromBundles:, use initWithContentsOfURL: to initialize the model. The URL uniquely identifies a model so that Core Data will not merge the current model with any legacy models.
1. Make sure that you clean any old build products before running the application. If the application bundle
itself contains old model files, you can delete the application.
2. Instead of mergedModelFromBundles:, use initWithContentsOfURL: to initialize the model. The URL uniquely identifies a model so that Core Data will not merge the current model with any legacy models.
Changing the Schema Makes a Model Incompatible With Old Stores
If you add a new entity or a new attribute to an existing entity, you will not be able to open old stores; if you add a validation constraint or set a new default value for an attribute, you will be able to open old stores.
If you add a new entity or a new attribute to an existing entity, you will not be able to open old stores; if you add a validation constraint or set a new default value for an attribute, you will be able to open old stores.
Important: Ifyouwanttochangethemodelbutalsoretaintheabilitytoopenstorescreatedusinga
previous version of the model, you must keep the previous version of the model (as a version in a versioned
model). Core Data cannot open a store for which it has no compatible model. Thus, if you want to change
the model but also retain the ability to open existing stores, you must:
-
Ensure that you have a versioned model—if you don’t, make the current model into a versioned model.
-
Before editing the schema , create a new version of the current model.
-
Edit the new current version of the model, leaving the old version unaltered.
Accessing and Using a Managed Object Model at Runtime
Thus to get
the model from a managed object context, you use the following code:
[[<#A managed object context#> persistentStoreCoordinator] managedObjectModel];
[[<#A managed object context#> persistentStoreCoordinator] managedObjectModel];
You can also retrieve the model from an entity description, so given a managed object you can retrieve its
entity description and hence the model, as shown in the following example.
[[<#A managed object#> entity] managedObjectModel];
Creating Fetch Request Templates Programmatically
Strings File
The easiest way to localize a model is to create a corresponding strings file—the strings file name is the same as the model file name, but with a .strings rather than a .xcdatamodel extension
"Property/salary" = "Salary";
Setting a Localization Dictionary Programmatically
You can set a localization dictionary at runtime using the NSManagedObjectModel method setLocalizationDictionary:
[[<#A managed object#> entity] managedObjectModel];
Creating Fetch Request Templates Programmatically
NSManagedObjectModel *model = <#Get a model#>;
NSFetchRequest *requestTemplate = [[NSFetchRequest alloc] init];
NSEntityDescription *publicationEntity =
[[model entitiesByName] objectForKey:@"Publication"];
[requestTemplate setEntity:publicationEntity];
NSPredicate *predicateTemplate = [NSPredicate predicateWithFormat:
@"(mainAuthor.firstName like[cd] $FIRST_NAME) AND \
(mainAuthor.lastName like[cd] $LAST_NAME) AND \
(publicationDate > $DATE)"];
[requestTemplate setPredicate:predicateTemplate];
[model setFetchRequestTemplate:requestTemplate
forName:@"PublicationsForAuthorSinceDate"];
Accessing Fetch Request Templates
[aManagedObjectContext executeFetchRequest:fetchRequest error:&error];
NSManagedObjectModel *model = <#Get a model#>;
NSError *error = nil;
NSDictionary *substitutionDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
NSError *error = nil;
NSDictionary *substitutionDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
@"Fiona", @"FIRST_NAME", @"Verde", @"LAST_NAME",
[NSDate dateWithTimeIntervalSinceNow:-31356000], @"DATE", nil];
NSFetchRequest *fetchRequest =
[model fetchRequestFromTemplateWithName:@"PublicationsForAuthorSinceDate"
substitutionVariables:substitutionDictionary];
NSArray *results =
Localizing a Managed Object Model
You localize a model by providing a localization dictionary that follows the pattern shown in the table below.
You localize a model by providing a localization dictionary that follows the pattern shown in the table below.
Key
|
Value
|
Note
|
"Entity/NonLocalizedEntityName"
|
"LocalizedEntityName"
|
|
"Property/NonLocalizedPropertyName/Entity/EntityName"
|
"LocalizedPropertyName"
|
1
|
"Property/NonLocalizedPropertyName"
|
"LocalizedPropertyName"
|
You can access the localization dictionary using the method localizationDictionary.
Strings File
The easiest way to localize a model is to create a corresponding strings file—the strings file name is the same as the model file name, but with a .strings rather than a .xcdatamodel extension
"Entity/Emp" = "Employee";
"Property/firstName" = "First Name";
"Property/lastName" = "Last Name";
Setting a Localization Dictionary Programmatically
You can set a localization dictionary at runtime using the NSManagedObjectModel method setLocalizationDictionary:
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] init];
NSEntityDescription *runEntity = [[NSEntityDescription alloc] init];
[runEntity setName:@"Run"];
[runEntity setManagedObjectClassName:@"Run"];
[mom setEntities:@[runEntity]];
NSMutableArray *runProperties = [NSMutableArray array];
NSAttributeDescription *dateAttribute = [[NSAttributeDescription alloc] init];
[runProperties addObject:dateAttribute];
[dateAttribute setName:@"date"];
[dateAttribute setAttributeType:NSDateAttributeType];
[dateAttribute setOptional:NO];
NSAttributeDescription *idAttribute= [[NSAttributeDescription alloc] init];
[runProperties addObject:idAttribute];
[idAttribute setName:@"processID"];
[idAttribute setAttributeType:NSInteger32AttributeType];
[idAttribute setOptional:NO];
[idAttribute setDefaultValue:@0];
NSPredicate *validationPredicate = [NSPredicate predicateWithFormat:@"SELF >= 0"];
NSString *validationWarning = @"Process ID < 0";[idAttribute setValidationPredicates:@[validationPredicate]
withValidationWarnings:@[validationWarning]];
[runEntity setProperties:runProperties];
NSDictionary *localizationDictionary = @{
@"Property/processID/Entity/Run" : @"Process ID",
@"Property/date/Entity/Run" : @"Date"
@"ErrorString/Process ID < 0" : @"Process ID must not be less than 0" };
[mom setLocalizationDictionary:localizationDictionary];
No comments:
Post a Comment