深入浅出Cocoa之Core Data(2)- 代码示例(一)

2014-11-24 02:33:32 · 作者: · 浏览: 5

前面详细讲解了 Core Data 的框架以及设计的类,下面我们来讲解一个完全手动编写代码使用这些类的示例,这个例子来自苹果官方示例。在这个例子里面,我们打算做这样一件事情:记录程序运行记录(时间与 process id),并保存到xml文件中。我们使用 Core Data 来做这个事情。
示例代码下载:点击这里

一,建立一个新的 Mac command-line tool application 工程,命名为 CoreDataTutorial。为支持垃圾主动回收机制,点击项目名称,在右边的 Build Setting 中查找 garbage 关键字,将找到的 Objective-C Garbage Collection 设置为 Required [-fobj-gc-only]。并将 main.m 中 的 main() 方法修改为如下:


int main (int argc, const char * argv[])
{
NSLog(@" === Core Data Tutorial ===");

// Enable GC
//
objc_startCollectorThread();

return 0;
}


二,创建并设置模型类

在 main() 之前添加如下方法:


NSManagedObjectModel *managedObjectModel()
{
static NSManagedObjectModel *moModel = nil;

if (moModel != nil) {
return moModel;
}

moModel = [[NSManagedObjectModel alloc] init];

// Create the entity
//
NSEntityDescription *runEntity = [[NSEntityDescription alloc] init];
[runEntity setName:@"Run"];
[runEntity setManagedObjectClassName:@"Run"];

[moModel setEntities:[NSArray arrayWithObject:runEntity]];

// Add the Attributes
//
NSAttributeDescription *dateAttribute = [[NSAttributeDescription alloc] init];
[dateAttribute setName:@"date"];
[dateAttribute setAttributeType:NSDateAttributeType];
[dateAttribute setOptional:NO];

NSAttributeDescription *idAttribute = [[NSAttributeDescription alloc] init];
[idAttribute setName:@"processID"];
[idAttribute setAttributeType:NSInteger32AttributeType];
[idAttribute setOptional:NO];
[idAttribute setDefaultValue:[NSNumber numberWithInteger:-1]];

// Create the validation predicate for the process ID.
// The following code is equivalent to validationPredicate = [NSPredicate predicateWithFormat:@"SELF > 0"]
//
NSExpression *lhs = [NSExpression expressionForeva luatedObject];
NSExpression *rhs = [NSExpression expressionForConstantValue:[NSNumber numberWithInteger:0]];

NSPredicate *validationPredicate = [NSComparisonPredicate
predicateWithLeftExpression:lhs
rightExpression:rhs
modifier:NSDirectPredicateModifier
type:NSGreaterThanPredicateOperatorType
options:0];

NSString *validationWarning = @"Process ID < 1";
[idAttribute setValidationPredicates:[NSArray arrayWithObject:validationPredicate]
withValidationWarnings:[NSArray arrayWithObject:validationWarning]];

// set the properties for the entity.
//
NSArray *properties = [NSArray arrayWithObjects: dateAttribute, idAttribute, nil];
[runEntity setProperties:properties];

// Add a Localization Dictionary
//
NSMutableDictionary *localizationDictionary = [NSMutableDictionary dictionary];
[localizationDictionary setObject:@"Date" forKey:@"Property/date/Entity/Run"];
[localizationDictionary setObject:@"Process ID" forKey:@"Property/processID/Entity/Run"];
[localizationDictionary setObject:@"Process ID must not be less than 1" forKey:@"ErrorString/Process ID < 1"];

[moModel setLocalizationDictionary:localizationDictionary];

return moModel;
}


在上面的代码中:
1)我们创建了一个全局模型 moModel;
2)并在其中创建一个名为 Run 的 Entity,这个 Entity 对应的 ManagedObject 类名为 Run(很快我们将创建这样一个类);
3)给 Run Entity 添加了两个必须的 Property:date 和 processID,分别表示运行时间以及进程 ID;并设置默认的进程 ID 为 -1;
4)给 processID 特性设置检验条件:必须大于 0;
5)给模型设置本地化描述词典;

本地化描述提供对 Entity,Property,Error信息等的便于理解的描述,其可用的键值对如下表:

Key
Value


"Entity/NonLocalizedEntityName"
"LocalizedEntityName"


"Property/NonLocalizedPropertyName/Entity/EntityName"
"LocalizedPropertyName"


"Property/NonLocalizedPropertyName"
"LocalizedPropertyName"


"ErrorString/NonLocalizedErrorString"
"LocalizedErrorString"


三,创建并设置运行时类和对象
由于要用到存储功能,所以我们必须定义持久化数据的存储路径,在 main() 之前添加如下方法设置存储路径:


NSURL *applicationLogDirectory()
{
NSString *LOG_DIRECTORY = @"CoreDataTutorial";
static NSURL *ald = nil;

if (ald == nil)
{
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSError *error = nil;
NSURL *libraryURL = [fileManager URLForDirectory:NSLibraryDirectory inDomain:NSUserDomainMask
appropriateForURL:nil create:YES error:&error];
if (libraryURL == nil) {
NSLog(@"Could not access Library directory\n%@", [error localizedDescription]);
}
else
{
ald = [libraryURL URLByAppendingPathComponent:@"Logs"];
ald = [ald URLByAppendingPathComponent:LOG_DIRECTORY];

NSLog(@" >> log path %@", [ald path]);

NSDictionary *properties = [ald resourceva luesForKeys:[NSArray arrayWithObject:NSURLIsDirectoryKey] error:&error];
if (properties == nil)
{
if (![fileManager createDirectoryAtPath:[ald path] withIntermediateDirectories:YES attributes:nil error:&error])
{
NSLog(@"Could not create directory %@\n%@",
[ald path], [error localizedDescription]);
ald = nil;
}
}
}
}

return ald;
}

在上面的代码中,我们将持久化数据文件保存到路径:/Users/kesalin/Library/Logs/CoreDataTutorial 下。
下面,我们来创建运行时对象:ManagedObjectContext 和 PersistentStoreCoordinator。
NSManagedObjectContext *managedObjectContext()
{
static NSManagedObjectContext *moContext = nil;
if (moContext != nil) {
return moContext;
}

moContext = [[NSManagedObje