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

羅朝輝(飄飄白云)

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

  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 羅朝輝 閱讀(3453) 評論(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>
            免费视频亚洲| 久久精品国产久精国产一老狼| 欧美α欧美αv大片| 亚洲欧美资源在线| a91a精品视频在线观看| 欧美成人综合| 久久天天狠狠| 久久久久亚洲综合| 久久精品水蜜桃av综合天堂| 性做久久久久久| 亚洲精品欧美专区| 99国产精品视频免费观看一公开 | 老司机久久99久久精品播放免费 | 亚洲激情国产精品| 在线观看欧美激情| 136国产福利精品导航| 在线观看日韩av电影| 国产精品任我爽爆在线播放| 国产精品私拍pans大尺度在线| 国产精品日韩一区二区三区| 国产裸体写真av一区二区| 国产精品揄拍500视频| 国产日韩欧美中文在线播放| 国产偷自视频区视频一区二区| 欧美日韩大陆在线| 国产精品一卡二卡| 国产真实久久| 国产精品美女久久| 欧美高清自拍一区| 欧美色精品天天在线观看视频 | 欧美人与禽猛交乱配视频| 国产精品久久久久久久久久ktv | 欧美一级黄色录像| 久久夜色精品一区| 欧美成人国产va精品日本一级| 欧美国产日韩一区二区| 欧美三级网页| 国产在线精品二区| 一二三区精品福利视频| 欧美一区二区三区免费视| 亚洲免费网站| 美玉足脚交一区二区三区图片| 国产欧美在线视频| 亚洲与欧洲av电影| 亚洲欧美自拍偷拍| 卡通动漫国产精品| 国产精品激情av在线播放| 国产亚洲综合性久久久影院| 日韩午夜高潮| 久久综合九色欧美综合狠狠| 亚洲成人在线视频播放| 最新日韩av| 久久激情五月婷婷| 欧美日韩不卡视频| 狠狠色狠狠色综合日日小说| 亚洲日本乱码在线观看| 午夜精品www| 91久久久久久国产精品| 久久成人18免费观看| 欧美日韩精品一区二区| 亚洲人成在线播放网站岛国| 久久国产精品99国产| 99精品国产福利在线观看免费| 久久精品免费电影| 国产欧美精品一区二区色综合| 亚洲精品裸体| 美女在线一区二区| 欧美一区亚洲| 国产精品久久久久久久久婷婷| 亚洲乱码视频| 亚洲高清二区| 欧美一区二区久久久| 国产精品一区二区三区四区| 99在线精品视频| 91久久综合| 欧美黄色影院| 日韩一级大片| 99成人免费视频| 欧美日韩国产在线观看| 亚洲视频精品| 在线亚洲欧美| 国产精品久久久久秋霞鲁丝| 国产精品久久久久久影视| 亚洲一区3d动漫同人无遮挡| 亚洲精品在线观看免费| 欧美日韩在线不卡| aa级大片欧美三级| 日韩视频在线观看免费| 久久久久久69| 在线观看日韩www视频免费 | 久久久久国产一区二区三区| 国语自产偷拍精品视频偷| 久久色中文字幕| 久久精品一二三| 亚洲高清在线视频| 免费在线播放第一区高清av| 麻豆久久久9性大片| 黄色成人在线观看| 国产精品乱码一区二区三区 | 久久久久久久综合| 亚洲国产高清一区二区三区| 亚洲成人在线视频网站| 欧美激情精品久久久久久免费印度| 国产女主播视频一区二区| 裸体女人亚洲精品一区| 欧美激情一区三区| 香蕉视频成人在线观看| 久久久国产精彩视频美女艺术照福利| 在线播放国产一区中文字幕剧情欧美 | 亚洲精品国产精品国自产在线| 欧美日韩国产成人高清视频| 91久久综合| 亚洲天堂男人| 狠狠色狠狠色综合| 亚洲另类自拍| 黄色日韩网站视频| 99精品国产在热久久婷婷| 国产亚洲亚洲| 日韩视频免费看| 国模叶桐国产精品一区| 亚洲精品乱码久久久久久蜜桃麻豆| 国产精品入口尤物| 亚洲欧洲日本专区| 国产精品一区二区三区久久| 亚洲日韩视频| 亚洲美女av电影| 美脚丝袜一区二区三区在线观看| 久久精品欧美| 国产色综合网| 欧美在线电影| 噜噜噜91成人网| 韩国精品在线观看| 久久精品99国产精品日本| 久久三级视频| 亚洲国产成人精品久久| 久久青草久久| 亚洲国产精品999| 亚洲日本欧美日韩高观看| 欧美国产日韩一区二区在线观看| 亚洲大片av| 亚洲毛片在线观看| 欧美视频二区36p| 一本一道久久综合狠狠老精东影业 | 欧美va天堂| 亚洲国产精品黑人久久久| 亚洲日本在线视频观看| 欧美久久久久久久| 9人人澡人人爽人人精品| 亚洲一区二区av电影| 国产精品大全| 欧美一级理论片| 蜜桃av久久久亚洲精品| 欧美成人资源| 国产色综合久久| 亚洲一区在线播放| 欧美一区二区免费| 国产一本一道久久香蕉| 欧美一区二区视频在线观看| 久久久午夜电影| 亚洲人成欧美中文字幕| 欧美精品一区二区在线观看| aa级大片欧美| 久久黄金**| 亚洲高清一二三区| 欧美日韩大片一区二区三区| 亚洲男人影院| 麻豆成人在线| 99精品免费| 国产日产精品一区二区三区四区的观看方式 | 国产精品久久婷婷六月丁香| 午夜亚洲一区| 欧美国产欧美综合 | 亚洲曰本av电影| 欧美大片网址| 午夜精品久久久久久久99樱桃| 国产综合婷婷| 欧美精品91| 欧美怡红院视频| 一本色道**综合亚洲精品蜜桃冫| 欧美在线欧美在线| 亚洲精品久久7777| 国产精品一区视频| 欧美激情一区二区三区成人| 午夜在线观看免费一区| 亚洲人成人一区二区在线观看| 校园春色国产精品| 亚洲精品一区二区三区不| 国产农村妇女精品一区二区| 欧美激情国产高清| 久久综合国产精品台湾中文娱乐网| 一区二区三区四区五区在线| 欧美第一黄网免费网站| 欧美一区二粉嫩精品国产一线天| 亚洲精品乱码久久久久久按摩观| 国产一区美女| 国产欧美日韩91| 国产精品久久久久aaaa九色| 欧美日韩mp4| 一区二区三区欧美亚洲| 欧美韩日高清|