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

羅朝輝(飄飄白云)

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

  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>
            国产亚洲一级高清| 国产精品你懂的在线| 久久久精品国产免大香伊| 欧美1区3d| 亚洲伊人久久综合| 欧美日韩另类视频| 亚洲视频在线播放| 欧美在线亚洲| 亚洲性线免费观看视频成熟| 欧美精品综合| 日韩视频免费观看高清完整版| 亚洲国产精品一区二区尤物区 | 国产精品久久97| 国产精品狠色婷| 国产亚洲精品久久飘花| 国内久久精品视频| 亚洲全部视频| 久久高清国产| 亚洲国产精品va在线看黑人动漫| 99国产精品| 久久精品成人一区二区三区| 欧美成人在线免费观看| 国产精品久线观看视频| 亚洲国产91精品在线观看| 亚洲午夜久久久久久尤物| 久久久久久亚洲精品不卡4k岛国| 亚洲人成7777| 欧美在线高清视频| 欧美新色视频| 亚洲人久久久| 欧美在线free| 亚洲欧洲久久| 久久久久久国产精品mv| 国产精品高清一区二区三区| 极品少妇一区二区| 亚洲一区二区在线免费观看| 欧美第十八页| 久久精品中文字幕一区| 国产精品久久久久永久免费观看| 国内激情久久| 午夜精品久久一牛影视| 亚洲大片免费看| 久久国产精品亚洲va麻豆| 国产精品av一区二区| 亚洲毛片视频| 欧美激情第3页| 久久色中文字幕| 国产午夜精品久久久久久免费视| 在线中文字幕日韩| 欧美激情综合色综合啪啪 | 久久久精品国产免费观看同学| 亚洲高清自拍| 乱码第一页成人| 狠狠久久亚洲欧美| 欧美在线黄色| 香蕉久久久久久久av网站| 欧美视频免费| 欧美日韩精品免费看| 在线观看中文字幕不卡| 久久不见久久见免费视频1| av成人免费在线| 欧美区高清在线| 夜夜嗨av色一区二区不卡| 亚洲电影免费观看高清完整版| 欧美一区二区三区免费视频| 国产日韩欧美在线看| 久久精品在这里| 久久美女性网| 亚洲黑丝在线| 亚洲第一网站免费视频| 欧美好骚综合网| 一区二区不卡在线视频 午夜欧美不卡在 | 亚洲国产精品999| 欧美成人激情视频| 久久久99国产精品免费| 黄色欧美日韩| 欧美成人免费在线观看| 欧美大片91| 99视频精品全部免费在线| 亚洲另类一区二区| 欧美少妇一区二区| 欧美在线一二三四区| 久久精品在这里| 99在线|亚洲一区二区| 日韩视频免费| 国语自产精品视频在线看一大j8 | 一区三区视频| 欧美激情bt| 国产精品久久久久国产a级| 欧美一区二区三区喷汁尤物| 久久精品1区| 99pao成人国产永久免费视频| 亚洲午夜国产成人av电影男同| 国产一区二区av| 亚洲日本电影| 国产一区二区三区无遮挡| 亚洲国产mv| 国产日韩精品一区二区| 亚洲高清在线观看一区| 国产欧美亚洲日本| 91久久精品国产91性色tv| 国产亚洲成精品久久| 亚洲激情一区二区三区| 国产欧美91| 日韩一级片网址| 今天的高清视频免费播放成人 | 亚洲日本中文字幕免费在线不卡| 亚洲人成网站777色婷婷| 国产精品你懂的在线欣赏| 久久综合九色综合网站| 国产精品99免费看 | 亚洲午夜久久久| 亚洲成人资源| 亚洲免费一区二区| 亚洲毛片网站| 久久亚洲精品欧美| 亚洲欧美综合另类中字| 久热精品在线| 久久久久久日产精品| 国产精品白丝jk黑袜喷水| 免费看亚洲片| 国产一区91| 亚洲欧美在线一区二区| 一区二区国产日产| 麻豆视频一区二区| 久久亚洲精品视频| 国产日韩在线亚洲字幕中文| 亚洲图片欧洲图片av| 亚洲视频在线一区| 欧美日韩国产综合新一区| 亚洲国产精品专区久久| 亚洲电影av| 久久综合五月天婷婷伊人| 久久一区激情| 国内偷自视频区视频综合| 欧美影院在线播放| 久久久久国产精品www| 韩日精品视频一区| 欧美一区二区三区免费观看视频| 欧美在线免费一级片| 国产亚洲毛片| 久久久女女女女999久久| 欧美二区在线播放| 亚洲三级视频| 欧美精品久久99| 一区二区电影免费在线观看| 中国av一区| 国产精品vvv| 亚洲欧美清纯在线制服| 久久免费视频在线| 亚洲国产综合在线看不卡| 欧美国产欧美综合 | 亚洲九九九在线观看| 欧美日韩一区二区在线观看| 亚洲午夜精品久久| 久久精品国产欧美激情| 黄色成人精品网站| 欧美理论在线| 亚洲免费视频成人| 另类专区欧美制服同性| 亚洲伦理在线免费看| 国产精品欧美久久久久无广告| 亚洲欧美精品在线| 久久免费国产精品1| 在线观看一区视频| 久久久久久久久久久久久女国产乱 | 亚洲男女毛片无遮挡| 国产精品推荐精品| 欧美一区二区三区的| 欧美成人免费大片| 亚洲一区二区在| 精品成人乱色一区二区| 欧美日韩岛国| 久久不射中文字幕| 亚洲人成在线观看一区二区| 午夜久久福利| 亚洲区第一页| 国产精品自拍一区| 欧美精品网站| 久久精品伊人| 亚洲一区二区三区免费在线观看| 久久夜色撩人精品| 亚洲欧美日韩中文播放| 亚洲国产精品va在线看黑人动漫| 欧美性猛片xxxx免费看久爱| 久久亚洲精品一区| 亚洲制服av| 亚洲美女啪啪| 欧美a级大片| 久久xxxx精品视频| 亚洲自拍偷拍麻豆| 夜夜狂射影院欧美极品| 伊人激情综合| 国产婷婷精品| 国产精品青草综合久久久久99| 欧美精品一区二区视频| 久久手机精品视频| 欧美一区午夜视频在线观看| 一区二区三区鲁丝不卡| 亚洲精品乱码久久久久久蜜桃麻豆|