青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

羅朝輝(飄飄白云)

關注嵌入式操作系統,移動平臺,圖形開發。-->加微博 ^_^

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
  85 隨筆 :: 0 文章 :: 169 評論 :: 0 Trackbacks

深入淺出 Cocoa 之 Core Data(2)- 代碼示例

CC 許可,轉載請注明出處

前面詳細講解了 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 expressionForEvaluatedObject];
    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 resourceValuesForKeys:[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 
= [[NSManagedObjectContext alloc] init];
    
    
// Create a persistent store coordinator, then set the coordinator for the context.
    
//
    NSManagedObjectModel *moModel = managedObjectModel();
    NSPersistentStoreCoordinator 
*coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:moModel];
    [moContext setPersistentStoreCoordinator: coordinator];
    
    
// Create a new persistent store of the appropriate type. 
    
//
    NSString *STORE_TYPE = NSXMLStoreType;
    NSString 
*STORE_FILENAME = @"CoreDataTutorial.xml";
    
    NSError 
*error = nil;
    NSURL 
*url = [applicationLogDirectory() URLByAppendingPathComponent:STORE_FILENAME];
    
    NSPersistentStore 
*newStore = [coordinator addPersistentStoreWithType:STORE_TYPE
                                                            configuration:nil
                                                                      URL:url
                                                                  options:nil
                                                                    error:
&error];
    
    
if (newStore == nil) {
        NSLog(
@"Store Configuration Failure\n%@", ([error localizedDescription] != nil) ? [error localizedDescription] : @"Unknown Error");
    }

    
return moContext;
}
在上面的代碼中:
1)我們創建了一個全局 ManagedObjectContext 對象 moContext;
2)并在設置其 persistent store coordinator,存儲類型為 xml,保存文件名為:CoreDataTutorial.xml,并將其放到前面定義的存儲路徑下。

 

好,至此萬事具備,只欠 ManagedObject 了!下面我們就來定義這個數據對象類。向工程添加 Core Data->NSManagedObject subclass 的類,名為 Run (模型中 Entity 定義的類名) 。

Run.h

//
//  Run.h
//  CoreDataTutorial
//
//  Created by kesalin on 8/29/11.
//  Copyright 2011 kesalin@gmail.com. All rights reserved.
//

#import 
<CoreData/NSManagedObject.h>

@interface Run : NSManagedObject
{
    NSInteger processID;
}

@property (retain) NSDate 
*date;
@property (retain) NSDate 
*primitiveDate;
@property NSInteger processID;

@end

 

Run.m
//
//  Run.m
//  CoreDataTutorial
//
//  Created by kesalin on 8/29/11.
//  Copyright 2011 kesalin@gmail.com. All rights reserved.
//

#import 
"Run.h"

@implementation Run

@dynamic date;
@dynamic primitiveDate;

- (void) awakeFromInsert
{
    [super awakeFromInsert];

    self.primitiveDate 
= [NSDate date];
}

#pragma mark 
-
#pragma mark Getter and setter

- (NSInteger)processID 
{
    [self willAccessValueForKey:
@"processID"];
    NSInteger pid 
= processID;
    [self didAccessValueForKey:
@"processID"];
    
return pid;
}

- (void)setProcessID:(NSInteger)newProcessID
{
    [self willChangeValueForKey:
@"processID"];
    processID 
= newProcessID;
    [self didChangeValueForKey:
@"processID"];
}

// Implement a setNilValueForKey: method. If the key is “processID” then set processID to 0.
//
- (void)setNilValueForKey:(NSString *)key {
    
    
if ([key isEqualToString:@"processID"]) {
        self.processID 
= 0;
    }
    
else {
        [super setNilValueForKey:key];
    }
}

@end

注意:
1)這個類中的 date 和 primitiveDate 的訪問屬性為 @dynamic,這表明在運行期會動態生成對應的 setter 和 getter;
2)在這里我們演示了如何正確地手動實現 processID 的 setter 和 getter:為了讓 ManagedObjecContext  能夠檢測 processID的變化,以及自動支持 undo/redo,我們需要在訪問和更改數據對象時告之系統,will/didAccessValueForKey 以及 will/didChangeValueForKey 就是起這個作用的。
3)當我們設置 nil 給數據對象 processID 時,我們可以在 setNilValueForKey 捕獲這個情況,并將 processID  置 0;
4)當數據對象被插入到 ManagedObjectContext 時,我們在 awakeFromInsert 將時間設置為當前時間。

 

三,創建或讀取數據對象,設置其值,保存
好,至此真正的萬事具備,我們可以創建或從持久化文件中讀取數據對象,設置其值,并將其保存到持久化文件中。本例中持久化文件為 xml 文件。修改 main() 中代碼如下:

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

    
// Enable GC
    
//
    objc_startCollectorThread();

    NSError 
*error = nil;
    
    NSManagedObjectModel 
*moModel = managedObjectModel();
    NSLog(
@"The managed object model is defined as follows:\n%@", moModel);
    
    
if (applicationLogDirectory() == nil) {
        exit(
1);
    }
    
    NSManagedObjectContext 
*moContext = managedObjectContext();
    
    
// Create an Instance of the Run Entity
    
//
    NSEntityDescription *runEntity = [[moModel entitiesByName] objectForKey:@"Run"];
    Run 
*run = [[Run alloc] initWithEntity:runEntity insertIntoManagedObjectContext:moContext];
    NSProcessInfo 
*processInfo = [NSProcessInfo processInfo];
    run.processID 
= [processInfo processIdentifier];
    
    
if (![moContext save: &error]) {
        NSLog(
@"Error while saving\n%@", ([error localizedDescription] != nil) ? [error localizedDescription] : @"Unknown Error");
        exit(
1);
    }
    
    
// Fetching Run Objects
    
//
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:runEntity];

    NSSortDescriptor 
*sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:YES];
    [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
    
    error 
= nil;
    NSArray 
*array = [moContext executeFetchRequest:request error:&error];
    
if ((error != nil) || (array == nil))
    {
        NSLog(
@"Error while fetching\n%@", ([error localizedDescription] != nil) ? [error localizedDescription] : @"Unknown Error");
        exit(
1);
    }
    
    
// Display the Results
    
//
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterMediumStyle];
    
    NSLog(
@"%@ run history:", [processInfo processName]);
    
    
for (run in array)
    {
        NSLog(
@"On %@ as process ID %ld", [formatter stringForObjectValue:run.date], run.processID);
    }
    
    
return 0;
}

 

在上面的代碼中:
1)我們先獲得全局的 NSManagedObjectModel 和 NSManagedObjectContext 對象:moModel 和 moContext;
2)并創建一個Run Entity,設置其 Property processID 為當前進程的 ID;
3)將該數據對象保存到持久化文件中:[moContext save: &error]。我們無需與 PersistentStoreCoordinator 打交道,只需要給 ManagedObjectContext 發送 save 消息即可,NSManagedObjectContext 會透明地在后面處理對持久化數據文件的讀寫;
4)然后我們創建一個 FetchRequest 來查詢持久化數據文件中保存的數據記錄,并將結果按照日期升序排列。查詢操作也是由 ManagedObjectContext 來處理的:[moContextexecuteFetchRequest:request error:&error];
5)將查詢結果打印輸出;

 

最后,不要忘記導入相關頭文件:

#import <Foundation/Foundation.h>
#import 
<CoreData/CoreData.h>
#include 
<objc/objc-auto.h>
#import 
"Run.h"

好!大功告成!編譯運行,我們可以得到如下顯示:
2011-09-03 21:42:47.556 CoreDataTutorial[992:903] CoreDataTutorial run history:
2011-09-03 21:42:47.557 CoreDataTutorial[992:903] On 2011-9-3 下午09:41:56 as process ID 940
2011-09-03 21:42:47.557 CoreDataTutorial[992:903] On 2011-9-3 下午09:42:16 as process ID 955
2011-09-03 21:42:47.558 CoreDataTutorial[992:903] On 2011-9-3 下午09:42:20 as process ID 965
2011-09-03 21:42:47.558 CoreDataTutorial[992:903] On 2011-9-3 下午09:42:24 as process ID 978
2011-09-03 21:42:47.559 CoreDataTutorial[992:903] On 2011-9-3 下午09:42:47 as process ID 992

 


通過這個例子,我們可以更好理解 Core Data  的運作機制。在 Core Data 中我們最常用的就是 ManagedObjectContext,它幾乎參與對數據對象的所有操作,包括對 undo/redo 的支持;而 Entity 對應的運行時類為 ManagedObject,我們可以理解為抽象數據結構 Entity 在內存中由 ManagedObject 來體現,而 Perproty 數據類型在內存中則由 ManagedObject 類的成員屬性來體現。一般我們不需要與 PersistentStoreCoordinator 打交道,對數據文件的讀寫操作都由 ManagedObjectContext 為我們代勞了。

posted on 2011-09-03 23:16 羅朝輝 閱讀(3459) 評論(0)  編輯 收藏 引用 所屬分類: Cocoa 開發
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美+亚洲+精品+三区| 国产精品久久久久久亚洲调教| 亚洲摸下面视频| 久久久亚洲综合| 午夜性色一区二区三区免费视频 | 亚洲第一页中文字幕| 欧美日韩国产综合视频在线| 男人的天堂成人在线| 国产农村妇女毛片精品久久麻豆 | 久久精品99国产精品日本 | 欧美亚洲视频一区二区| 欧美精品日日鲁夜夜添| 免费不卡在线观看av| 国际精品欧美精品| 亚洲尤物影院| 午夜精品久久久久久| 欧美日韩中文字幕| 日韩午夜视频在线观看| 亚洲精品偷拍| 欧美国产激情二区三区| 女女同性女同一区二区三区91| 国产午夜精品全部视频在线播放| 亚洲午夜免费视频| 亚洲欧美日韩天堂| 国产精品九九久久久久久久| 99精品国产在热久久婷婷| 99在线热播精品免费| 欧美日本久久| aaa亚洲精品一二三区| 亚洲一级片在线看| 国产精品成人一区二区艾草| 中文国产一区| 午夜在线不卡| 国产在线高清精品| 久久精品中文字幕一区| 巨乳诱惑日韩免费av| 亚洲国产91| 欧美激情黄色片| 一区二区三区四区国产| 欧美一区二视频在线免费观看| 欧美日韩国产亚洲一区 | 亚洲日韩欧美视频| 夜夜爽夜夜爽精品视频| 国产精品www| 性18欧美另类| 久久综合色天天久久综合图片| 在线观看91久久久久久| 欧美凹凸一区二区三区视频| 亚洲免费黄色| 久久成人资源| 亚洲高清不卡| 欧美日韩综合一区| 欧美一区二区视频在线观看| 女同性一区二区三区人了人一| 亚洲精品视频免费| 国产精品毛片在线| 久久婷婷一区| 中国亚洲黄色| 欧美成人tv| 亚洲欧美日韩国产成人| 韩国一区电影| 欧美日韩精品一区二区天天拍小说 | 欧美资源在线观看| 在线电影院国产精品| 欧美日韩在线三区| 久久九九久精品国产免费直播| 亚洲国产视频一区| 性色av一区二区三区| 91久久一区二区| 国产精品你懂的| 欧美v亚洲v综合ⅴ国产v| 亚洲男人第一网站| 亚洲福利免费| 久久精品天堂| 亚洲在线不卡| 亚洲激情视频网站| 国产美女一区| 欧美精品一区三区| 久久阴道视频| 亚洲欧美在线x视频| 亚洲九九九在线观看| 美女主播一区| 久久精彩免费视频| 午夜精品成人在线| 在线亚洲电影| 亚洲精品美女| 亚洲二区在线视频| 韩国av一区二区| 国产精品亚洲片夜色在线| 欧美精品一区三区在线观看| 美女任你摸久久| 久久精品72免费观看| 欧美一级淫片aaaaaaa视频| 一区二区欧美日韩| 999在线观看精品免费不卡网站| 欧美二区在线播放| 免费短视频成人日韩| 久久香蕉国产线看观看av| 欧美一区二区三区另类| 亚洲一区免费视频| 亚洲一区视频| 亚洲中字在线| 亚洲午夜激情网站| 亚洲图片在线| 亚洲天堂av高清| 亚洲私人影院在线观看| 中文欧美日韩| 亚洲一区二区高清视频| 这里只有精品视频| 亚洲一区二区免费| 亚洲欧美日韩国产中文在线| 亚洲视频在线观看视频| 亚洲免费在线视频一区 二区| 亚洲小说欧美另类婷婷| 亚洲欧美国产精品桃花| 亚洲女女女同性video| 亚洲女ⅴideoshd黑人| 欧美亚洲三级| 久久躁狠狠躁夜夜爽| 久久夜色精品国产亚洲aⅴ| 久久综合电影一区| 欧美激情在线狂野欧美精品| 亚洲国产一区二区在线| 亚洲欧洲在线播放| 亚洲午夜小视频| 欧美一级视频| 欧美成人免费在线观看| 欧美日韩高清免费| 国产精品亚洲精品| 在线成人av.com| 日韩视频二区| 欧美一区二区免费视频| 可以免费看不卡的av网站| 亚洲高清一区二区三区| 9色国产精品| 久久精品视频播放| 欧美高清在线一区| 国产模特精品视频久久久久| 精品动漫3d一区二区三区免费版| 亚洲电影第三页| 亚洲视频一二三| 久久久久久成人| 亚洲国产精品精华液2区45| 亚洲视频中文字幕| 久久久久中文| 欧美色图天堂网| 精品51国产黑色丝袜高跟鞋| 日韩视频一区二区三区在线播放免费观看| 中文亚洲字幕| 欧美高清在线观看| 亚洲一区二区三区视频| 免播放器亚洲一区| 国产伦精品一区二区三区照片91| 亚洲国产日韩在线一区模特| 午夜伦理片一区| 欧美激情在线观看| 欧美怡红院视频| 欧美日韩国内自拍| 亚洲丰满少妇videoshd| 欧美一级一区| 亚洲精选在线观看| 老色批av在线精品| 国产嫩草影院久久久久| 亚洲视频www| 欧美激情一区二区三区成人| 亚洲欧美日产图| 欧美日韩国产首页在线观看| 亚洲黄页一区| 久久躁狠狠躁夜夜爽| 亚洲一级网站| 欧美视频免费在线观看| 亚洲精品欧美极品| 老牛国产精品一区的观看方式| 一本久久综合亚洲鲁鲁五月天| 久色婷婷小香蕉久久| 国产一区二区久久| 久久国产婷婷国产香蕉| 一区二区三区四区五区精品| 欧美福利在线| 亚洲激情电影中文字幕| 美女久久一区| 久久久久久午夜| 国内成人自拍视频| 久久成年人视频| 亚洲网站啪啪| 国产精品国产亚洲精品看不卡15| 日韩一区二区精品葵司在线| 欧美韩日高清| 免费欧美在线| 亚洲黄页一区| 亚洲人成在线观看一区二区| 欧美 亚欧 日韩视频在线| 影音先锋在线一区| 欧美成人免费网站| 蜜臀av性久久久久蜜臀aⅴ四虎 | 亚洲欧美成人精品| 一区二区欧美在线| 国产精品欧美久久| 欧美一区国产在线| 欧美亚洲自偷自偷|