CoreData及MagicalRecord學(xué)習(xí)

本文是對(duì) MagicalRecord github上的翻譯

正文:
注意: MagicalRecord 在 ARC 下運(yùn)作,Core Data 是 ORM 方案,據(jù)說(shuō)帶來(lái)的麻煩比好處多,且 Core Data 建立的表沒(méi)有主鍵,但對(duì)于數(shù)據(jù)庫(kù)沒(méi)有性能要求,進(jìn)行簡(jiǎn)單的數(shù)據(jù)操作完全夠用,能簡(jiǎn)化無(wú)數(shù)的代碼量.

In software engineering, the active record pattern is a design pattern found in software that stores its data in relational databases. It was named by Martin Fowler in his book Patterns of Enterprise Application Architecture. The interface to such an object would include functions such as Insert, Update, and Delete, plus properties that correspond more-or-less directly to the columns in the underlying database table.
在軟件工程中,對(duì)象與數(shù)據(jù)庫(kù)中的記錄實(shí)時(shí)映射是一種設(shè)計(jì)模式,在處理關(guān)系型數(shù)據(jù)庫(kù)的的軟件中多有出現(xiàn).這種設(shè)計(jì)模式被記錄在 Martin Fowler 的<Patterns of Enterprise Application Architecture> 中.被操作對(duì)象的接口應(yīng)該包含增刪改查的方法,基本屬性不多不少的剛好與數(shù)據(jù)庫(kù)中的一條記錄相對(duì)應(yīng).

Active record is an approach to accessing data in a database. A database table or view is wrapped into a class; thus an object instance is tied to a single row in the table. After creation of an object, a new row is added to the table upon save. Any object loaded gets its information from the database; when an object is updated, the corresponding row in the table is also updated. The wrapper class implements accessor methods or properties for each column in the table or view.
實(shí)時(shí)映射記錄是一種操作數(shù)據(jù)庫(kù)的方式,一個(gè)數(shù)據(jù)庫(kù)的表被封裝成一個(gè)對(duì)象;這個(gè)對(duì)象中的一個(gè)實(shí)例會(huì)對(duì)應(yīng)著該表中的一條記錄.當(dāng)創(chuàng)建一個(gè)對(duì)象時(shí),一條記錄也被插入到表中并保存起來(lái).任何被加載的對(duì)象中的屬性信息都從數(shù)據(jù)庫(kù)中讀取;當(dāng)一個(gè)對(duì)象更新時(shí),這個(gè)數(shù)據(jù)庫(kù)表中對(duì)應(yīng)的記錄也會(huì)更新.這個(gè)被封裝的類實(shí)現(xiàn)了實(shí)時(shí)操作的方法,且其屬性一一對(duì)應(yīng)于數(shù)據(jù)庫(kù)中表的屬性.

Wikipedia 維基百科
MagicalRecord was inspired by the ease of Ruby on Rails' Active Record fetching. The goals of this code are:
? Clean up my Core Data related code
? Allow for clear, simple, one-line fetches
? Still allow the modification of the NSFetchRequest when request optimizations are needed
MagicalRecord 靈感來(lái)自于簡(jiǎn)潔的Ruby語(yǔ)言中 Rails' Active Record 查詢方式. MagicalRecord 這個(gè)開(kāi)源庫(kù)的核心思想是:
清除 Core Data 相關(guān)的代碼
簡(jiǎn)潔的清除,簡(jiǎn)單的一行搜索記錄的功能
當(dāng)然允許使用NSFetchRequest,當(dāng)存在著復(fù)雜的搜索條件時(shí)

Installing MagicalRecord 安裝

Using CocoaPods
One of the easiest ways to integrate MagicalRecord in your project is to use CocoaPods:
Add the following line to your Podfile:
a. Plain
pod "MagicalRecord"
b. With CocoaLumberjack as Logger
pod "MagicalRecord/CocoaLumberjack"
In your project directory, run pod update
You should now be able to add #import <MagicalRecord/MagicalRecord.h> to any of your target's source files and begin using MagicalRecord!
最簡(jiǎn)單的融入MagicalRecord到你的工程的一個(gè)方法是使用CocoaPods
添加以下的標(biāo)示到你的Podfile文件
a.簡(jiǎn)單的
pod "MagicalRecord"
b.用CocoaLumberjack記錄器
pod "MagicalRecord/CocoaLumberjack"
在你的項(xiàng)目目錄中,運(yùn)行更新倉(cāng)
你現(xiàn)在應(yīng)該可以添加#import < MagicalRecord / MagicalRecord.h >到任何源文件并開(kāi)始使用MagicalRecord !

**Shorthand Category Methods **速記分類方法

By default, all of the category methods that MagicalRecord provides are prefixed with MR_. This is inline with Apple's recommendation not to create unadorned category methods to avoid naming clashes.
If you like, you can include the following headers to use shorter, non-prefixed category methods:
默認(rèn)情況下,所有的MR_ MagicalRecord提供的類方法是以MR_為前綴。這是(內(nèi)聯(lián)與)根據(jù)蘋(píng)果的建議而不是創(chuàng)建不加裝飾的分類方法來(lái)避免命名沖突绸狐。
如果你喜歡,你可以包括下列使用短的標(biāo)題,沒(méi)有前綴的分類方法:

#import <MagicalRecord/MagicalRecord.h>
#import <MagicalRecord/MagicalRecord+ShorthandMethods.h>
#import <MagicalRecord/MagicalRecordShorthandMethodAliases.h>

If you're using Swift, you'll need to add these imports to your target's Objective-C bridging header.
Once you've included the headers, you should call the +[MagicalRecord enableShorthandMethods] class method before you setup/use MagicalRecord:
如果你使用Swift卤恳、你需要添加這些入口到你的目標(biāo)的objective - c橋接頭文件。
一旦你包括標(biāo)題,在你設(shè)置/使用MagicalRecord:之前你應(yīng)該喚起+[MagicalRecord enableShorthandMethods]類方法

  • (void)theMethodWhereYouSetupMagicalRecord
    {
    [MagicalRecord enableShorthandMethods];
    // Setup MagicalRecord as per usual 設(shè)置MagicalRecord按往常一樣
    }
**Please note that we do not offer support for this feature**. If it doesn't work, [please file an issue](https://github.com/magicalpanda/MagicalRecord/issues/new) and we'll fix it when we can.
請(qǐng)注意,我們不支持這個(gè)功能寒矿。如果它不工作,請(qǐng)文件描述問(wèn)題,當(dāng)我們可能的時(shí)候我們會(huì)解決它突琳。

- [Getting Started](https://github.com/magicalpanda/MagicalRecord/blob/master/Docs/Getting-Started.md)

>To get started, import the MagicalRecord.h header file in your project's pch file. This will allow a global include of all the required headers.
首先,導(dǎo)入MagicalRecord.h頭文件在您的項(xiàng)目的pch文件。這將允許全局包括所有需要的頭文件符相。
If you're using CocoaPods or MagicalRecord.framework, your import should look like:
如果你使用CocoaPods或MagicalRecord框架,你的導(dǎo)入應(yīng)該看起來(lái)像:

// Objective-C

import <MagicalRecord/MagicalRecord.h>

// Swift
import MagicalRecord

Otherwise, if you've added MagicalRecord's source files directly to your Objective-C project, your import should be:    
否則,如果你已經(jīng)直接地添加MagicalRecord的源文件到你的 objective - c項(xiàng)目中,你的導(dǎo)入應(yīng)該是:
    #import "MagicalRecord.h"
Next, somewhere in your app delegate, in either the - applicationDidFinishLaunching: withOptions: method, or -awakeFromNib, use one of the following setup calls with the MagicalRecord class:
接下來(lái),在您的應(yīng)用程序委托的一些地方,無(wú)論是- applicationDidFinishLaunching:withOptions:方法,或-awakefromnib,使用以下設(shè)置的一個(gè)調(diào)用MagicalRecord類:
  • (void)setupCoreDataStack;
  • (void)setupAutoMigratingCoreDataStack;
  • (void)setupCoreDataStackWithInMemoryStore;
  • (void)setupCoreDataStackWithStoreNamed:(NSString *)storeName;
  • (void)setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName;
  • (void)setupCoreDataStackWithStoreAtURL:(NSURL *)storeURL;
  • (void)setupCoreDataStackWithAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL;
Each call instantiates one of each piece of the Core Data stack, and provides getter and setter methods for these instances. These well known instances to MagicalRecord, and are recognized as "defaults".
每次調(diào)用所有實(shí)例化各個(gè)核心數(shù)據(jù)棧之一,并為這些實(shí)例提供了getter和setter方法拆融。這些眾所周知的實(shí)例MagicalRecord,被認(rèn)為是“默認(rèn)的”。
When using the default SQLite data store with the DEBUG flag set, changing your model without creating a new model version will cause MagicalRecord to delete the old store and create a new one automatically. This can be a huge time saver — no more needing to uninstall and reinstall your app every time you make a change your data model! Please be sure not to ship your app with DEBUG enabled: Deleting your app's data without telling the user about it is really bad form!
當(dāng)使用默認(rèn)SQLite數(shù)據(jù)存儲(chǔ)用DEBUG調(diào)試標(biāo)記設(shè)置,改變你的模型沒(méi)有創(chuàng)建一個(gè)新的模型版本的時(shí)候?qū)?dǎo)致MagicalRecord刪除舊的存儲(chǔ)和自動(dòng)創(chuàng)建一個(gè)新的啊终。這可以節(jié)省大量時(shí)間,每次你改變你的數(shù)據(jù)模型就不再需要卸載和重新安裝應(yīng)用程序镜豹。請(qǐng)確保不要將你的應(yīng)用程序與調(diào)試功能連接:刪除應(yīng)用程序的數(shù)據(jù)而沒(méi)有告訴用戶它是非常糟糕的!
Before your app exits, you should call +cleanUp class method:
在程序退出之前,你應(yīng)該調(diào)用+ cleanUp清理類方法:

[MagicalRecord cleanUp];

This tidies up after MagicalRecord, tearing down our custom error handling and setting all of the Core Data stack created by MagicalRecord to nil.      
這要收拾在MagicalRecord后,拆除我們的自定義錯(cuò)誤處理和設(shè)置所有的由MagicalRecord創(chuàng)建的核心數(shù)據(jù)堆棧為零。

>**iCloud-enabled Persistent Stores iCloud功能的持久存儲(chǔ)**
To take advantage of Apple's iCloud Core Data syncing, use one of the following setup methods in place of the standard methods listed in the previous section:  
利用蘋(píng)果的iCloud核心數(shù)據(jù)同步,使用以下設(shè)置方法之一 代替 在前一節(jié)中列出的標(biāo)準(zhǔn)方法:
>```
>+ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID
                              localStoreNamed:(NSString *)localStore;

>+ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID
                               contentNameKey:(NSString *)contentNameKey
                              localStoreNamed:(NSString *)localStoreName
                      cloudStorePathComponent:(NSString *)pathSubcomponent;

>+ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID
                               contentNameKey:(NSString *)contentNameKey
                              localStoreNamed:(NSString *)localStoreName
                      cloudStorePathComponent:(NSString *)pathSubcomponent
                                   completion:(void (^)(void))completion;

>+ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID
                              localStoreAtURL:(NSURL *)storeURL;

>+ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID
                               contentNameKey:(NSString *)contentNameKey
                              localStoreAtURL:(NSURL *)storeURL
                      cloudStorePathComponent:(NSString *)pathSubcomponent;

>+ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID
                               contentNameKey:(NSString *)contentNameKey
                              localStoreAtURL:(NSURL *)storeURL
                      cloudStorePathComponent:(NSString *)pathSubcomponent
                                   completion:(void (^)(void))completion;
>```

>For further details, please refer to [Apple's "iCloud Programming Guide for Core Data"](https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/Introduction/Introduction.html#//apple_ref/doc/uid/TP40013491). 
要了解進(jìn)一步的細(xì)節(jié),請(qǐng)參閱蘋(píng)果的iCloud編程指南的核心數(shù)據(jù)蓝牲。

>**Notes**
If you are managing multiple iCloud-enabled stores, we recommended that you use one of the longer setup methods that allows you to specify your own contentNameKey. The shorter setup methods automatically generate theNSPersistentStoreUbiquitousContentNameKey based on your app's bundle identifier (CFBundleIdentifier):
如果您管理多個(gè)iCloud-enabled商店,我們建議您使用一個(gè)較長(zhǎng)的設(shè)置方法,允許您指定自己的contentNameKey趟脂。較短的設(shè)置方法自動(dòng)生成基于應(yīng)用程序的包標(biāo)識(shí)符(CFBundleIdentifier):的NSPersistentStoreUbiquitousContentNameKey

- [Working with Managed Object Contexts](https://github.com/magicalpanda/MagicalRecord/blob/master/Docs/Working-with-Managed-Object-Contexts.md)

>**Working with Managed Object Contexts  工作與管理對(duì)象上下文**

>**Creating New Contexts 創(chuàng)建新環(huán)境**
A variety of simple class methods are provided to help you create new contexts:  
提供各種簡(jiǎn)單的類方法來(lái)幫助您創(chuàng)建新的上下文:
- **+[NSManagedObjectContext MR_newContext]**: Sets the default context as it's parent context. Has a concurrency type of NSPrivateQueueConcurrencyType.
設(shè)置默認(rèn)上下文作為它的父上下文。有一個(gè)并發(fā)的NSPrivateQueueConcurrencyType類型例衍。
- **+[NSManagedObjectContext MR_newMainQueueContext]**: Has a concurrency type of NSMainQueueConcurrencyType.
一種并發(fā)NSMainQueueConcurrencyType類型昔期。
- **+[NSManagedObjectContext MR_newPrivateQueueContext]**: Has a concurrency type of NSPrivateQueueConcurrencyType.
一種并發(fā)NSPrivateQueueConcurrencyType 類型。
- **+[NSManagedObjectContext MR_newContextWithParent:…]**: Allows you to specify the parent context that will be set. Has a concurrency type of NSPrivateQueueConcurrencyType.
允許您指定將被設(shè)置的父上下文肄渗。有一個(gè)并發(fā)的NSPrivateQueueConcurrencyType類型镇眷。
- **+[NSManagedObjectContext MR_newContextWithStoreCoordinator:…]**: Allows you to specify the persistent store coordinator for the new context. Has a concurrency type of NSPrivateQueueConcurrencyType.
允許您指定持久性存儲(chǔ)協(xié)調(diào)員作為新的上下文。有一個(gè)并發(fā)的NSPrivateQueueConcurrencyType類型翎嫡。

>**The Default Context  默認(rèn)的上下文**
When working with Core Data, you will regularly deal with two main objects: NSManagedObject and NSManagedObjectContext. 
使用Core Data時(shí),您將定期處理兩個(gè)主要對(duì)象:NSManagedObject NSManagedObjectContext欠动。
MagicalRecord provides a simple class method to retrieve a default NSManagedObjectContext that can be used throughout your app. This context operates on the main thread, and is great for simple, single-threaded apps.        
MagicalRecord提供了一個(gè)簡(jiǎn)單的類方法來(lái)檢索一個(gè)默認(rèn)的可以始終在你的App使用的NSManagedObjectContext,。這種上下文運(yùn)行在主線程,且十分的簡(jiǎn)單,單線程應(yīng)用在程序中。
To access the default context, call:   訪問(wèn)默認(rèn)上下文,使用:

NSManagedObjectContext *defaultContext = [NSManagedObjectContext MR_defaultContext];

This context will be used throughout MagicalRecord in any method that uses a context, but does not provde a specific managed object context parameter.  
在使用一個(gè)上下文的任何方法里具伍,這種上下文將貫穿整個(gè)MagicalRecord使用翅雏,但并不能驗(yàn)證特定管理對(duì)象上下文參數(shù)。
If you need to create a new managed object context for use in non-main threads, use the following method:   
如果您需要?jiǎng)?chuàng)建一個(gè)新的管理對(duì)象上下文用于非主線程,使用下面的方法:

NSManagedObjectContext *myNewContext = [NSManagedObjectContext MR_newContext];

This will create a new managed object context which has the same object model and persistent store as the default context, but is safe for use on another thread. It automatically sets the default context as it's parent context. 
這將會(huì)創(chuàng)建一個(gè)新的管理對(duì)象上下文人芽,它有相同的對(duì)象模型和持久化存儲(chǔ)作為默認(rèn)上下文,但是是安全的使用在另一個(gè)線程上望几。它會(huì)自動(dòng)設(shè)置默認(rèn)上下文作為父上下文。
If you'd like to make your myNewContext instance the default for all fetch requests, use the following class method:    
如果你想讓你的myNewContext實(shí)例默認(rèn)的為所有獲取請(qǐng)求,使用以下類方法:

[NSManagedObjectContext MR_setDefaultContext:myNewContext];

**NOTE**: It is highly recommended that the default context is created and set on the main thread using a managed object context with a concurrency type of NSMainQueueConcurrencyType.
注意:強(qiáng)烈建議默認(rèn)上下文被創(chuàng)建且使用管理對(duì)象上下文設(shè)置在主線程用并發(fā)NSMainQueueConcurrencyType類型萤厅。

>**Performing Work on Background Threads        在后臺(tái)線程執(zhí)行工作**
MagicalRecord provides methods to set up and work with contexts for use in background threads. The background saving operations are inspired by the UIView animation block methods, with a few minor differences:   
MagicalRecord提供方法來(lái)設(shè)置和使用上下文在后臺(tái)線程中使用橄抹。后臺(tái)操作受UIView動(dòng)畫(huà)塊方法,有一些細(xì)微的差別:
?  The block in which you make changes to your entities will never be executed on the main thread.  
你改變實(shí)體的塊永遠(yuǎn)不會(huì)在主線程上執(zhí)行。
?  A single NSManagedObjectContext is provided for you within these blocks. 
單個(gè)NSManagedObjectContext為你提供在這些街區(qū)惕味。
For example, if we have Person entity, and we need to set the firstName and lastName fields, this is how you would use MagicalRecord to setup a background context for your use:
例如,如果我們有實(shí)體的人,我們需要設(shè)置firstName和lastName字段,這是如何使用MagicalRecord設(shè)置背景為您的使用環(huán)境:
>```
>Person *person = ...;

>[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)>{

  >Person *localPerson = [person MR_inContext:localContext];
  >localPerson.firstName = @"John";
 > localPerson.lastName = @"Appleseed";

>}];
>```
In this method, the specified block provides you with the proper context in which to perform your operations, you don't need to worry about setting up the context so that it tells the Default Context that it's done, and should update because changes were performed on another thread.
在這種方法中,指定的塊為您提供適當(dāng)?shù)纳舷挛膩?lái)執(zhí)行您的操作,你不需要擔(dān)心設(shè)置上下文,以便它告訴默認(rèn)上下文,就完成了,而且應(yīng)該更新,因?yàn)樾薷牧硪粋€(gè)線程上執(zhí)行楼誓。
To perform an action after this save block is completed, you can fill in a completion block:
塊后執(zhí)行一個(gè)動(dòng)作完成后,你可以填寫(xiě)完成塊:
>```
>Person *person = ...;

>[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)>{

  >Person *localPerson = [person MR_inContext:localContext];
  >localPerson.firstName = @"John";
  >localPerson.lastName = @"Appleseed";

>} completion:^(BOOL success, NSError *error) {

  >self.everyoneInTheDepartment = [Person findAll];

>}];

>```
This completion block is called on the main thread (queue), so this is also safe for triggering UI updates.
這個(gè)完成塊呼吁主線程(隊(duì)列),所以這也是安全的觸發(fā)UI更新。

- [Creating Entities](https://github.com/magicalpanda/MagicalRecord/blob/master/Docs/Creating-Entities.md)

>**Creating Entities  創(chuàng)建實(shí)體**
To create and insert a new instance of an Entity in the default context, you can use:  
創(chuàng)建和插入一個(gè)新實(shí)例的實(shí)體在缺省情況下,您可以使用:

Person *myPerson = [Person MR_createEntity];```
To create and insert an entity into specific context:
創(chuàng)建和插入一個(gè)實(shí)體特定上下文:

Person *myPerson = [Person MR_createEntityInContext:otherContext];```

- [Deleting Entities](https://github.com/magicalpanda/MagicalRecord/blob/master/Docs/Deleting-Entities.md)

>**Deleting Entities  刪除實(shí)體**
To delete a single entity in the default context: 
刪除一個(gè)單一的實(shí)體在默認(rèn)上下文:

[myPerson MR_deleteEntity];```
To delete the entity from a specific context:
刪除實(shí)體從一個(gè)特定的背景:

[myPerson MR_deleteEntityInContext:otherContext];```
To truncate all entities from the default context:  
從默認(rèn)的上下文截?cái)嗨袑?shí)體:

[Person MR_truncateAll];```
To truncate all entities in a specific context:
截?cái)嗨袑?shí)體在一個(gè)特定的背景:

[Person MR_truncateAllInContext:otherContext];```

- [Fetching Entities](https://github.com/magicalpanda/MagicalRecord/blob/master/Docs/Fetching-Entities.md)

>###**Fetching Entities     獲取實(shí)體**

>**Basic Finding    基本的發(fā)現(xiàn)**
Most methods in MagicalRecord return an NSArray of results. 
大多數(shù)方法MagicalRecord NSArray返回的結(jié)果名挥。
As an example, if you have an entity named *Person* related to a *Department* entity (as seen in many of [Apple's Core Data examples](https://github.com/magicalpanda/MagicalRecord/blob/master/Docs/.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdBasics.html#/apple_ref/doc/uid/TP40001650-TP1)), you can retrieve all of the *Person* entities from your persistent store using the following method: 
作為一個(gè)例子,如果你有一個(gè)Person實(shí)體相關(guān)部門實(shí)體(正如在很多蘋(píng)果的核心數(shù)據(jù)的例子),你可以從持久存儲(chǔ)中檢索所有人的實(shí)體使用以下方法:

NSArray *people = [Person MR_findAll];```
To return the same entities sorted by a specific attribute:
返回相同的實(shí)體按特定的屬性:

NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName"
                                         ascending:YES];```
To return the entities sorted by multiple attributes:       
返回的實(shí)體排序由多個(gè)屬性:

NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName,FirstName"
ascending:YES];```
To return the results sorted by multiple attributes with different values. If you don't provide a value for any attribute, it will default to whatever you've set in your model:
返回結(jié)果按多個(gè)屬性具有不同的值疟羹。如果你不為任何屬性提供一個(gè)值,它將默認(rèn)為你已經(jīng)在你的模型:

NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName:NO,FirstName"
                                     ascending:YES];

// OR

NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName,FirstName:YES"
ascending:NO];```
If you have a unique way of retrieving a single object from your data store (such as an identifier attribute), you can use the following method:
如果你有一個(gè)獨(dú)特的檢索方式從數(shù)據(jù)存儲(chǔ)一個(gè)對(duì)象(比如一個(gè)標(biāo)識(shí)符屬性),您可以使用以下方法:

Person *person = [Person MR_findFirstByAttribute:@"FirstName"
                                       withValue:@"Forrest"];```

>**Advanced Finding 先進(jìn)的發(fā)現(xiàn)**
If you want to be more specific with your search, you can use a predicate:  
如果你想要更具體的和你的搜索,你可以使用一個(gè)謂詞:

NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", @[dept1, dept2]];
NSArray *people = [Person MR_findAllWithPredicate:peopleFilter];```

Returning an NSFetchRequest 返回一個(gè)NSFetchRequest

NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments];
NSFetchRequest *people = [Person MR_requestAllWithPredicate:peopleFilter];```
For each of these single line calls, an NSFetchRequest and NSSortDescriptors for any sorting criteria are created.  
每個(gè)一行調(diào)用,一個(gè)NSFetchRequest NSSortDescriptors創(chuàng)建的任何分類標(biāo)準(zhǔn)。

>**Customizing the Request  自定義請(qǐng)求**
>```
>NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments];

>NSFetchRequest *peopleRequest = [Person MR_requestAllWithPredicate:peopleFilter];
>[peopleRequest setReturnsDistinctResults:NO];
>[peopleRequest setReturnPropertiesNamed:@[@"FirstName", @"LastName"]];

>NSArray *people = [Person MR_executeFetchRequest:peopleRequest];```

>**Find the number of entities  找到實(shí)體的數(shù)量**
You can also perform a count of all entities of a specific type in your persistent store:   
您還可以執(zhí)行特定類型的所有實(shí)體的計(jì)算你的持久性存儲(chǔ):

NSNumber *count = [Person MR_numberOfEntities];```
Or, if you're looking for a count of entities based on a predicate or some filter:
或者,如果你正在尋找一個(gè)計(jì)數(shù)的實(shí)體基于謂詞或一些過(guò)濾器:

NSNumber *count = [Person MR_numberOfEntitiesWithPredicate:...];```
There are also complementary methods which return NSUInteger rather than NSNumber instances:        
也有互補(bǔ)的方法,返回了NSUInteger而不是NSNumber實(shí)例:
  • (NSUInteger) MR_countOfEntities;
  • (NSUInteger) MR_countOfEntitiesWithContext:(NSManagedObjectContext *)context;
  • (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter;
  • (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter
    inContext:(NSManagedObjectContext *)context;

>**Aggregate Operations 聚合操作**
>```
>NSNumber *totalCalories = [CTFoodDiaryEntry MR_aggregateOperation:@"sum:"
                                                      onAttribute:@"calories"
                                                    withPredicate:predicate];

>NSNumber *mostCalories  = [CTFoodDiaryEntry MR_aggregateOperation:@"max:"
                                                      onAttribute:@"calories"
                                                    withPredicate:predicate];

>NSArray *caloriesByMonth = [CTFoodDiaryEntry MR_aggregateOperation:@"sum:"
                                                       onAttribute:@"calories"
                                                     withPredicate:predicate
                                                           groupBy:@"month"];
>```

>**Finding entities in a specific context   發(fā)現(xiàn)實(shí)體在一個(gè)特定的上下文**
All find, fetch, and request methods have an inContext: method parameter that allows you to specify which managed object context you'd like to query:   
所有發(fā)現(xiàn),取回,并要求有它的方法:方法參數(shù),允許您指定管理對(duì)象上下文你想查詢:
>```
>NSArray *peopleFromAnotherContext = [Person MR_findAllInContext:someOtherContext];

>Person *personFromContext = [Person MR_findFirstByAttribute:@"lastName"
                                                  withValue:@"Gump"
                                                  inContext:someOtherContext];

>NSUInteger count = [Person MR_numberOfEntitiesWithContext:someOtherContext];

Saving Entities 保存實(shí)體

When should I save? 當(dāng)我要保存嗎?
In general, your app should save to it's persistent store(s) when data changes. Some applications choose to save on application termination, however this shouldn't be necessary in most circumstances — in fact, if you're only saving when your app terminates, you're risking data loss! What happens if your app crashes? The user will lose all the changes they've made — that's a terrible experience, and easily avoided.
一般來(lái)說(shuō),應(yīng)用程序應(yīng)該保存到它的持久性存儲(chǔ)(s)當(dāng)數(shù)據(jù)更改的時(shí)候禀倔。一些應(yīng)用程序選擇節(jié)省應(yīng)用程序終止,然而這個(gè)應(yīng)該是不必要的在大多數(shù)情況下——事實(shí)上,如果你只保存應(yīng)用程序終止時(shí),你面臨著丟失數(shù)據(jù)!如果你的應(yīng)用程序崩潰,會(huì)發(fā)生什么?用戶將失去他們的所有更改,這是一個(gè)可怕的經(jīng)歷,且容易避免榄融。
If you find that saving is taking a long time, there are a couple of things you should consider doing:
如果你發(fā)現(xiàn)保存很長(zhǎng)一段時(shí)間,有幾件事情你應(yīng)該考慮做:
1 . Save in a background thread: MagicalRecord provides a simple, clean API for making changes to your entities and subsequently saving them in a background thread — for example:
保存在一個(gè)后臺(tái)線程:MagicalRecord提供了一個(gè)簡(jiǎn)單,干凈的API更改你的實(shí)體和隨后保存在一個(gè)后臺(tái)線程,例如:

[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
        >// Do your work to be saved here, against the `localContext` instance
       > // Everything you do in this block will occur on a background thread
    
    >} completion:^(BOOL success, NSError *error) {
            [application endBackgroundTask:bgTask];
            bgTask = UIBackgroundTaskInvalid;
    >}];```

2 . Break the task down into smaller saves: tasks like importing large amounts of data should always be broken down into smaller chunks. There's no one-size-fits all rule for how much data you should be saving in one go, so you'll need to measure your application's performance using a tool like Apple's Instruments and tune appropriately.

把任務(wù)分解成較小的保存:任務(wù)導(dǎo)入大量數(shù)據(jù)應(yīng)該被分解成小塊。沒(méi)有統(tǒng)一的規(guī)則你應(yīng)該節(jié)約多少數(shù)據(jù),所以你需要測(cè)量應(yīng)用程序的性能使用像蘋(píng)果這樣的工具的工具和適當(dāng)調(diào)整救湖。

Handling Long-running Saves 處理長(zhǎng)期保存

On iOS 在iOS
When an application terminates on iOS, it is given a small window of opportunity to tidy up and save any data to disk. If you know that a save operation is likely to take a while, the best approach is to request an extension to your application's expiration, like so:
iOS應(yīng)用程序終止時(shí),它給出一個(gè)小機(jī)會(huì)整理并保存任何數(shù)據(jù)到磁盤愧杯。如果你知道一個(gè)保存操作可能需要一段時(shí)間,最好的方法是請(qǐng)求的擴(kuò)展應(yīng)用程序的過(guò)期,像這樣:

UIApplication *application = [UIApplication sharedApplication];

__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];

[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {

>// Do your work to be saved here

} completion:^(BOOL success, NSError *error) {
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];

Be sure to carefully [read the documentation for beginBackgroundTaskWithExpirationHandler
](https://developer.apple.com/library/iOS/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/beginBackgroundTaskWithExpirationHandler:), as inappropriately or unnecessarily extending your application's lifetime may earn your app a rejection from the App Store.  
beginBackgroundTaskWithExpirationHandler一定要仔細(xì)閱讀文檔,不當(dāng)或不必要的擴(kuò)展應(yīng)用程序的生命周期可能會(huì)贏得你的應(yīng)用程序從應(yīng)用程序商店拒絕。

>**On OS X  在OS X**
On OS X Mavericks (10.9) and later, App Nap can cause your application to act as though it is effectively terminated when it is in the background. If you know that a save operation is likely to take a while, the best approach is to disable automatic and sudden termination temporarily (assuming that your app supports these features):  
在OS X小牛(10.9)和后,應(yīng)用午睡會(huì)使您的應(yīng)用程序充當(dāng)雖然有效地終止時(shí)的背景捎谨。如果你知道一個(gè)保存操作可能需要一段時(shí)間,最好的方法是暫時(shí)禁用自動(dòng)和突然終止(假設(shè)您的應(yīng)用程序支持這些特性):
>```
>NSProcessInfo *processInfo = [NSProcessInfo processInfo];

>[processInfo disableSuddenTermination];
>[processInfo disableAutomaticTermination:@"Application is currently saving to persistent store"];

>[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {

    >// Do your work to be saved here

>} completion:^(BOOL success, NSError *error) {
    [processInfo enableSuddenTermination];
    [processInfo enableAutomaticTermination:@"Application has finished saving to the persistent store"];
>}];

As with the iOS approach, be sure to read the documentation on NSProcessInfo before implementing this approach in your app.
與iOS的方法,一定要閱讀文檔在NSProcessInfo實(shí)施這種方法在你的應(yīng)用程序民效。

Changes to saving in MagicalRecord 2.3.0 變化在MagicalRecord tripwire儲(chǔ)蓄

Context For Current Thread Deprecation 當(dāng)前線程上下文棄用
In earlier releases of MagicalRecord, we provided methods to retrieve the managed object context for the thread that the method was called on. Unfortunately, it's not possible to return the context for the currently executing thread in a reliable manner anymore. Grand Central Dispatch (GCD) makes no guarantees that a queue will be executed on a single thread, and our approach was based upon the older NSThread API while CoreData has transitioned to use GCD. For more details, please see Saul's post "Why contextForCurrentThread Doesn't Work in MagicalRecord".
MagicalRecord的早期版本中,我們提供了方法來(lái)檢索管理對(duì)象上下文的線程的方法被稱為憔维。不幸的是,它是不可能返回當(dāng)前執(zhí)行的線程的上下文以可靠的方式了涛救。中央調(diào)度(GCD)毫無(wú)保證隊(duì)列將單個(gè)線程上執(zhí)行,和我們的方法是基于老NSThread API雖然CoreData轉(zhuǎn)換到使用腎小球囊性腎病。有關(guān)詳細(xì)信息,請(qǐng)參閱掃羅的文章“為什么MagicalRecord contextForCurrentThread行不通”业扒。
In MagicalRecord 2.3.0, we continue to use +MR_contextForCurrentThread internally in a few places to maintain compatibility with older releases. These methods are deprecated, and you will be warned if you use them.
在MagicalRecord tripwire,我們繼續(xù)使用+ MR_contextForCurrentThread內(nèi)部在一些地方保持兼容老版本检吆。這些方法被棄用,你會(huì)警告說(shuō)如果你使用它們。
In particular, do not use +MR_contextForCurrentThread from within any of the +[MagicalRecord saveWithBlock:…] methods — the returned context may not be correct!
特別是,不使用+從內(nèi)部MR_contextForCurrentThread任何+[MagicalRecord saveWithBlock:…]方法——返回上下文可能不是正確的!
If you'd like to begin preparing for the change now, please use the method variants that accept a "context" parameter, and use the context that's passed to you in the +[MagicalRecord saveWithBlock:…] method block. Instead of:
如果你想開(kāi)始準(zhǔn)備改變現(xiàn)在,請(qǐng)使用方法的變體,接受“上下文”參數(shù),并使用上下文傳遞給你的+(MagicalRecord saveWithBlock:…)方法程储。而不是:

[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
    NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntity];
    // …
}];

You should now use:
現(xiàn)在,您應(yīng)該使用:

[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
    NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntityInContext:localContext];
    // …
}];

When MagicalRecord 3.0 is released, the context for current thread methods will be removed entirely. The methods that do not accept a "context" parameter will move to using the default context of the default stack — please see the MagicalRecord 3.0 release notes for more details.
MagicalRecord 3.0發(fā)布時(shí),當(dāng)前線程的上下文方法完全將被刪除蹭沛。方法,不接受“上下文”參數(shù)將使用默認(rèn)上下文默認(rèn)的堆棧-請(qǐng)參閱MagicalRecord 3.0發(fā)行說(shuō)明了解更多細(xì)節(jié)。

Changes to saving in MagicalRecord 2.2.0 改變?cè)贛agicalRecord 2.2.0儲(chǔ)蓄
In MagicalRecord 2.2, the APIs for saving were revised to behave more consistently, and also to follow naming patterns present in Core Data. Extensive work has gone into adding automated tests that ensure the save methods (both new and deprecated) continue to work as expected through future updates.
在MagicalRecord 2.2中,儲(chǔ)蓄的api是修改后的表現(xiàn)更加一致,并遵循命名模式出現(xiàn)在核心數(shù)據(jù)章鲤。廣泛的工作已經(jīng)進(jìn)入添加自動(dòng)化測(cè)試,確保保存方法(新和棄用)繼續(xù)工作如預(yù)期在未來(lái)的更新摊灭。
MR_save has been temporarily restored to it's original state of running synchronously on the current thread, and saving to the persistent store. However, the MR_save method is marked as deprecated and will be removed in the next major release of MagicalRecord (version 3.0). You should use MR_saveToPersistentStoreAndWait if you want the same behaviour in future versions of the library.
MR_save已經(jīng)暫時(shí)恢復(fù)到原始狀態(tài)的運(yùn)行在當(dāng)前線程同步,并保存到持久性存儲(chǔ)。然而,MR_save方法標(biāo)記為過(guò)時(shí)的,將被刪除的下一個(gè)主要版本MagicalRecord(版本3.0)败徊。您應(yīng)該使用MR_saveToPersistentStoreAndWait如果你想同樣的行為在未來(lái)版本的庫(kù)帚呼。

New Methods 新方法
The following methods have been added: 添加了以下方法:
NSManagedObjectContext+MagicalSaves

? - (void) MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion;
? - (void) MR_saveToPersistentStoreWithCompletion:(MRSaveCompletionHandler)completion;
? - (void) MR_saveOnlySelfAndWait;
? - (void) MR_saveToPersistentStoreAndWait;
? - (void) MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion;

MagicalRecord+Actions

? + (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;
? + (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;
? + (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block;
? + (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;
? + (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block;

Deprecations 的用法
The following methods have been deprecated in favour of newer alternatives, and will be removed in MagicalRecord 3.0:
下列方法已被棄用的新選擇,和將被刪除在MagicalRecord 3.0:
NSManagedObjectContext+MagicalSaves

? - (void) MR_save;
? - (void) MR_saveWithErrorCallback:(void(^)(NSError *error))errorCallback;
? - (void) MR_saveInBackgroundCompletion:(void (^)(void))completion;
? - (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback;
? - (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;
? - (void) MR_saveNestedContexts;
? - (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback;
? - (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;

MagicalRecord+Actions

? + (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;
? + (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block;
? + (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))completion;
? + (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *error))errorHandler;

Importing Data 導(dǎo)入數(shù)據(jù)
We're working on updating this documentation — thanks for your patience. For the moment, please refer to Importing Data Made Easy at Cocoa Is My Girlfriend. Much of this document is based upon Saul's work in that original article.
我們正在更新這個(gè)文檔,謝謝你的耐心。目前,請(qǐng)參考導(dǎo)入數(shù)據(jù)很容易在可可是我的女朋友。本文基于掃羅的工作在原來(lái)的文章煤杀。
MagicalRecord Team
MagicalRecord團(tuán)隊(duì)
MagicalRecord can help import data from standard NSObject instances such as NSArray and NSDictionary directly into your Core Data store.
MagicalRecord可以幫助導(dǎo)入數(shù)據(jù)從標(biāo)準(zhǔn)如NSArray和NSDictionary NSObject實(shí)例直接進(jìn)入你的核心數(shù)據(jù)存儲(chǔ)眷蜈。
It's a two step process to import data from an external source into your persistent store using MagicalRecord:
這是一個(gè)兩步的過(guò)程,從外部源數(shù)據(jù)導(dǎo)入到持久性存儲(chǔ)使用MagicalRecord:

  1. Define how the data you're importing maps to your store using your data model (it's pretty much codeless!)
    定義如何將數(shù)據(jù)導(dǎo)入映射到你的商店使用您的數(shù)據(jù)模型(幾乎無(wú)代碼!)
  2. Perform the data import
    執(zhí)行數(shù)據(jù)導(dǎo)入

Define Your Import 定義您的進(jìn)口
Data from external sources can be wildly variable in quality and structure, so we've done our best to make MagicalRecord's import processes flexible.
從外部數(shù)據(jù)源的數(shù)據(jù)可以廣泛的變量在質(zhì)量和結(jié)構(gòu),所以我們已經(jīng)盡力使MagicalRecord的進(jìn)口流程靈活。

MagicalRecord can import data from any Key-Value Coding (KVC) compliant object. We usually find people work withNSArray and NSDictionary instances, but it works just fine with any KVC compliant NSObject subclass.
MagicalRecord可以導(dǎo)入數(shù)據(jù)從任何鍵值編碼(現(xiàn)有的)兼容的對(duì)象沈自。我們通常發(fā)現(xiàn)人們使用NSArray和NSDictionary實(shí)例,但它工作得很好與任何現(xiàn)有的兼容NSObject子類酌儒。
MagicalRecord makes use of the Xcode data modeling tool's "User Info" values to allow configuration of import options and mappings possible without having to edit any code.
MagicalRecord使用Xcode數(shù)據(jù)建模工具的“用戶信息”值允許進(jìn)口的配置選項(xiàng)和映射可能不需要修改任何代碼。

Paste_Image.png

For reference: The user info keys and values are held in an NSDictionary that is attached to every entity, attribute and relationship in your data model, and can be accessed via the userInfo method on your NSEntityDescriptioninstances.
供參考:用戶信息鍵和值在NSDictionary附在每一個(gè)實(shí)體,屬性和關(guān)系數(shù)據(jù)模型,可以通過(guò)用戶信息訪問(wèn)方法NSEntityDescription實(shí)例枯途。
Xcode's data modelling tools give you access to this dictionary via the Data Model Inspector's "User Info" group. When editing a data model, you can open this inspector using Xcode's menus — View > Utilities > Show Data Model Inspector, or press ??3 on your keyboard.
Xcode的數(shù)據(jù)建模工具給你訪問(wèn)這個(gè)字典通過(guò)數(shù)據(jù)模型檢查器的“用戶信息”忌怎。在編輯一個(gè)數(shù)據(jù)模型時(shí),您可以使用Xcode的菜單,打開(kāi)這個(gè)檢查員視圖>工具>顯示數(shù)據(jù)模型檢查器,或按??3鍵盤上。
By default, MagicalRecord will automatically try to match attribute and relationship names with the keys in your imported data. If an attribute or relationship name in your model matches a key in your data, you don't need to do anything — the value attached to the key will be imported automatically.
默認(rèn)情況下,MagicalRecord會(huì)自動(dòng)嘗試匹配鍵的屬性和關(guān)系名稱您導(dǎo)入的數(shù)據(jù)酪夷。如果一個(gè)屬性或關(guān)系名稱在您的數(shù)據(jù)模型匹配的關(guān)鍵,你不需要做任何事情——價(jià)值將自動(dòng)導(dǎo)入的關(guān)鍵呆躲。
For example, if an attribute on an entity has the name 'firstName', MagicalRecord will assume the key in the data to import will also have a key of 'firstName' — if it does, your entity's firstName attribute will be set to the value of the firstName key in your data.
舉個(gè)例子,如果一個(gè)屬性對(duì)一個(gè)實(shí)體的名字“firstName”,MagicalRecord假設(shè)關(guān)鍵數(shù)據(jù)的導(dǎo)入也將一個(gè)關(guān)鍵的“firstName”——如果是這樣,你的實(shí)體firstName屬性的值將被設(shè)置為firstName的關(guān)鍵數(shù)據(jù)。
More often than not, the keys and structure in the data you are importing will not match your entity's attributes and relationships. In this case, you will need to tell MagicalRecord how to map your import data's keys to the correct attribute or relationship in your data model.
往往,鑰匙和結(jié)構(gòu)數(shù)據(jù)的導(dǎo)入不會(huì)匹配您的實(shí)體的屬性和關(guān)系捶索。在這種情況下,您將需要告訴MagicalRecord如何導(dǎo)入數(shù)據(jù)的鍵映射到正確的屬性或關(guān)系數(shù)據(jù)模型插掂。
Each of the three key objects we deal with in Core Data — Entities, Attributes and Relationships — have options that may need to be specified via user info keys:
我們每三個(gè)關(guān)鍵對(duì)象的處理核心數(shù)據(jù)——實(shí)體,屬性和關(guān)系,選項(xiàng)可能通過(guò)用戶信息需要指定鍵:
Attributes

Attributes.png

Entities
Entities.png

Relationships
Relationships.png

Importing Objects 進(jìn)口物品
To import data into your store using MagicalRecord, you need to know two things:
使用MagicalRecord數(shù)據(jù)導(dǎo)入到你的店鋪,你需要知道兩件事:

  1. The format of the data you're importing, and how it
    The basic idea behind MagicalRecord's importing is that you know the entity the data should be imported into, so you then write a single line of code tying this entity with the data to import. There are a couple of options to kick off the import process.
    你導(dǎo)入的格式數(shù)據(jù),以及它如何MagicalRecord背后的基本理念的導(dǎo)入,你知道實(shí)體應(yīng)該導(dǎo)入的數(shù)據(jù),所以你寫(xiě)一行代碼將這個(gè)實(shí)體的數(shù)據(jù)導(dǎo)入。有一些選項(xiàng)來(lái)啟動(dòng)導(dǎo)入過(guò)程腥例。
    To automatically create a new instance from the object, you can use the following, shorter approach:
    自動(dòng)創(chuàng)建一個(gè)新實(shí)例的對(duì)象,您可以使用以下,較短的方法:
NSDictionary *contactInfo = // Result from JSON parser or some other source

Person *importedPerson = [Person MR_importFromObject:contactInfo];

You can also use a two-stage approach:
您還可以使用一個(gè)兩階段的方法:

NSDictionary *contactInfo = // Result from JSON parser or some other source

Person *person = [Person MR_createEntity]; // This doesn't have to be a new entity
[person MR_importValuesForKeysWithObject:contactInfo];

The two-stage approach can be helpful if you’re looking to update an existing object by overwriting its attributes.
兩階段方法可以幫助如果你想通過(guò)覆蓋更新現(xiàn)有對(duì)象的屬性辅甥。
+MR_importFromObject: will look for an existing object based on the configured lookup value (see the relatedByAttribute andattributeNameID). Also notice how this follows the built in paradigm of importing a list of key-value pairs in Cocoa, as well as following the safe way to import data.
+MR_importFromObject:將尋找現(xiàn)有對(duì)象的基礎(chǔ)上,查找配置值(見(jiàn)relatedByAttribute attributeNameID)。也注意到此前范式的建立進(jìn)口可可豆中的鍵值對(duì)列表,以及導(dǎo)入數(shù)據(jù)的安全方法燎竖。
The +MR_importFromObject: class method provides a wrapper around creating a new object using the previously mentioned-MR_importValuesForKeysWithObject: instance method, and returns the newly created object filled with data.
+MR_importFromObject:類方法提供了一個(gè)包裝使用前面提到的-MR_importValuesForKeysWithObject:創(chuàng)建一個(gè)新的對(duì)象實(shí)例方法,并返回新創(chuàng)建的對(duì)象數(shù)據(jù)璃弄。
A key item of note is that both these methods are synchronous. While some imports will take longer than others, it’s still highly advisable to perform all imports in the background so as to not impact user interaction. As previously discussed, MagicalRecord provides a handy API to make using background threads more manageable:
注意的是,這兩種方法的一個(gè)關(guān)鍵項(xiàng)是同步的。雖然一些進(jìn)口將比別人花費(fèi)更多的時(shí)間,它仍然是高度建議執(zhí)行所有進(jìn)口的背景,以便不影響用戶交互构回。正如前面所討論的那樣,MagicalRecord提供了一個(gè)方便的API來(lái)使用后臺(tái)線程更易于管理:

[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *)localContext {
  Person *importedPerson = [Person MR_importFromObject:personRecord inContext:localContext];
}];```

>**Importing Arrays 輸入數(shù)組**
It’s common for a list of data to be served using a JSON array, or you’re importing a large list of a single type of data. The details of importing such a list are taken care of in the +MR_importFromArray: class method.
公共的數(shù)據(jù)是使用JSON數(shù)組,或者你導(dǎo)入一個(gè)大型的單一類型的數(shù)據(jù)列表夏块。進(jìn)口的細(xì)節(jié)中照顧這樣一個(gè)列表+ MR_importFromArray:類方法。

NSArray *arrayOfPeopleData = /// result from JSON parser
NSArray *people = [Person MR_importFromArray:arrayOfPeopleData];

This method, like +MR_importFromObject: is also synchronous, so for background importing, use the previously mentioned helper method for performing blocks in the background.   
這種方法,像+ MR_importFromObject:也是同步的,所以對(duì)于背景導(dǎo)入,使用前面提到的輔助方法用于執(zhí)行塊的背景纤掸。
If your import data exactly matches your Core Data model, then read no further because the aforementioned methods are all you need to import your data into your Core Data store. However, if your data, like most, has little quirks and minor deviations, then read on, as we’ll walk through some of the features of MagicalRecord that will help you handle several commonly encountered deviations.        
如果你導(dǎo)入數(shù)據(jù)完全匹配你的核心數(shù)據(jù)模型,然后閱讀不再因?yàn)榍懊嫣岬降姆椒ǘ际切枰愕臄?shù)據(jù)導(dǎo)入到你的核心數(shù)據(jù)存儲(chǔ)脐供。最喜歡的,但是,如果您的數(shù)據(jù)小怪癖和輕微的偏差,然后繼續(xù)讀下去,當(dāng)我們穿過(guò)的一些特性MagicalRecord會(huì)幫助你處理一些常見(jiàn)的偏差。

>**Best Practice    最佳實(shí)踐**

>**Handling Bad Data When Importing 處理錯(cuò)誤數(shù)據(jù)在導(dǎo)入**
APIs can often return data that has inconsistent formatting or values. The best way to handle this is to use the import category methods on your entity classes. There are three provided:      
api會(huì)返回?cái)?shù)據(jù)格式不一致或值借跪。處理這個(gè)問(wèn)題的最好方法是使用進(jìn)口的方法在你的實(shí)體類政己。提供有三種:
![Handling Bad Data When Importing.png](http://upload-images.jianshu.io/upload_images/1907575-255fc78b4e43c357.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Generally, if your data is bad you'll want to fix what the import did after an attempt has been made to import any values.      
一般來(lái)說(shuō),如果您的數(shù)據(jù)是壞你要解決什么導(dǎo)入后一直嘗試導(dǎo)入任何值。
A common scenario is importing JSON data where numeric strings can often be misinterpreted as an actual number. If you want to ensure that a value is imported as a string, you could do the following: 
一個(gè)常見(jiàn)的場(chǎng)景是進(jìn)口JSON數(shù)據(jù),數(shù)字字符串常常被誤解為一個(gè)實(shí)際的數(shù)字掏愁。如果你想確保一個(gè)值是進(jìn)口作為一個(gè)字符串,你可以做以下幾點(diǎn):

>```
>@interface MyGreatEntity

>@property(readwrite, nonatomic, copy) NSString *identifier;

>@end

>@implementation MyGreatEntity

>@dynamic identifier;

>- (void)didImport:(id)data
{
  if (NO == [data isKindOfClass:[NSDictionary class]]) {
    return;
}

  >NSDictionary *dataDictionary = (NSDictionary *)data;

  >id identifierValue = dataDictionary[@"my_identifier"];

  >if ([identifierValue isKindOfClass:[NSNumber class]]) {
    NSNumber *numberValue = (NSNumber *)identifierValue;
    self.identifier = [numberValue stringValue];
  }
}

>@end
>```

>**Deleting local records on import update  刪除本地導(dǎo)入更新記錄**
Sometimes you will want to make sure that subsequent import operations not only update but also delete local records that are not included as part of the remote dataset. To do this, fetch all local records not included in this update via theirrelatedByAttribute (id in the example below) and remove them immediately before importing the new dataset.   
有時(shí)你會(huì)想要確保后續(xù)導(dǎo)入操作不僅更新也刪除本地記錄,不包括作為遠(yuǎn)程數(shù)據(jù)集的一部分歇由。為此,獲取所有本地記錄不包含在此更新通過(guò)relatedByAttribute在下面的例子中(id)和刪除它們之前立即導(dǎo)入新數(shù)據(jù)集。

>```
NSArray *arrayOfPeopleData = /// result from JSON parser
NSArray *people = [Person MR_importFromArray:arrayOfPeopleData];
NSArray *idList = [arrayOfPeopleData valueForKey:@"id"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT(id IN %@)", idList];
[Person MR_deleteAllMatchingPredicate:predicate];

>```
If you also want to make sure that related records are removed during this update, you can use similar logic as above but implement it in the willImport: method of Person      
如果你也想要確保在這更新相關(guān)記錄被刪除,您可以使用類似的邏輯willImport如上,但實(shí)現(xiàn)它:方法的人
>```
>@implementation Person

>-(void)willImport:(id)data {
    NSArray *idList = [data[@"posts"] valueForKey:@"id"];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT(id IN %@) AND person.id == %@", idList, self.id];
    [Post MR_deleteAllMatchingPredicate:predicate];
}
>```
Source: http://stackoverflow.com/a/24252825/401092

- [Logging](https://github.com/magicalpanda/MagicalRecord/blob/master/Docs/Logging.md)

>**Logging  日志記錄**
MagicalRecord has logging built in to most of its interactions with Core Data. When errors occur during fetching or saving data, these errors are captured and (if you've enabled them) logged to the console.  
MagicalRecord日志建立在與核心數(shù)據(jù)的交互。當(dāng)錯(cuò)誤發(fā)生在抓取或保存數(shù)據(jù)時(shí),這些錯(cuò)誤捕獲和(如果你使他們)登錄到控制臺(tái)。
Logging is configured to output debugging messages (MagicalRecordLoggingLevelDebug) by default in debug builds, and will output error messages (MagicalRecordLoggingLevelError) in release builds.      
日志配置為默認(rèn)輸出調(diào)試信息(MagicalRecordLoggingLevelDebug)在調(diào)試構(gòu)建,并將輸出錯(cuò)誤消息(MagicalRecordLoggingLevelError)發(fā)布構(gòu)建塘揣。
Logging can be configured by calling [MagicalRecord setLoggingLevel:]; using one of the predefined logging levels:  
日志可以通過(guò)調(diào)用配置(MagicalRecord setLoggingLevel:];使用一個(gè)預(yù)定義的日志記錄級(jí)別:
?   MagicalRecordLogLevelOff: Don't log anything    不要什么日志
?   MagicalRecordLoggingLevelError: Log all errors      記錄所有錯(cuò)誤
?   MagicalRecordLoggingLevelWarn: Log warnings and errors  日志警告和錯(cuò)誤
?   MagicalRecordLoggingLevelInfo: Log informative, warning and error messages  日志信息,警告和錯(cuò)誤消息
?   MagicalRecordLoggingLevelDebug: Log all debug, informative, warning and error messages  記錄所有調(diào)試信息,警告和錯(cuò)誤消息
?   MagicalRecordLoggingLevelVerbose: Log verbose diagnostic, informative, warning and error messages   日志詳細(xì)的診斷信息,警告和錯(cuò)誤消息
The logging level defaults to MagicalRecordLoggingLevelWarn.    
MagicalRecordLoggingLevelWarn日志級(jí)別默認(rèn)值。

>**CocoaLumberjack**
If it's available, MagicalRecord will direct its logs to [CocoaLumberjack](https://github.com/CocoaLumberjack/CocoaLumberjack). All you need to do is make sure you've imported CocoaLumberjack before you import MagicalRecord, like so: 
如果可用,MagicalRecord將直接CocoaLumberjack的日志谢谦。所有你需要做的是確保進(jìn)口CocoaLumberjack進(jìn)口MagicalRecord之前,就像這樣:

// Objective-C

import <CocoaLumberjack/CocoaLumberjack.h>

import <MagicalRecord/MagicalRecord.h>

// Swift
import CocoaLumberjack
import MagicalRecord


>**Disabling Logging Completely 完全禁用日志記錄**
For most people this should be unnecessary. Setting the logging level to MagicalRecordLogLevelOff will ensure that no logs are printed. 
對(duì)大多數(shù)人來(lái)說(shuō)這應(yīng)該是不必要的。將日志級(jí)別設(shè)置為MagicalRecordLogLevelOff將確保不打印日志。
Even when using MagicalRecordLogLevelOff, a very quick check may be performed whenever a log call is made. If you absolutely need to disable the logging, you will need to define the following when compiling MagicalRecord:   
即使使用MagicalRecordLogLevelOff,快速檢查可能只要一個(gè)日志調(diào)用執(zhí)行他宛。如果您絕對(duì)需要禁用日志記錄,您將需要編譯MagicalRecord時(shí)定義如下:

define MR_LOGGING_DISABLED 1 #定義MR_LOGGING_DISABLED 1```

Please note that this will only work if you've added MagicalRecord's source to your own project. You can also add this to the MagicalRecord project's OTHER_CFLAGS as -DMR_LOGGING_DISABLED=1.
請(qǐng)注意,這只會(huì)工作如果你MagicalRecord源添加到自己的項(xiàng)目船侧。您還可以添加這個(gè)MagicalRecord項(xiàng)目的OTHER_CFLAGS -DMR_LOGGING_DISABLED = 1。

Resources 資源
The following articles highlight how to install and use aspects of MagicalRecord:
下面的文章強(qiáng)調(diào)如何MagicalRecord的安裝和使用方面:
How to make Programming with Core Data Pleasant 如何使編程與核心數(shù)據(jù)愉快嗎
Using Core Data with MagicalRecord 與MagicalRecord使用核心數(shù)據(jù)
Super Happy Easy Fetching in Core Data 超級(jí)快樂(lè)在核心數(shù)據(jù)容易獲取
Core Data and Threads, without the Headache 核心數(shù)據(jù)和線程,沒(méi)有頭痛
Unit Testing with Core Data 單元測(cè)試與核心數(shù)據(jù)

**Support **支持

MagicalRecord is provided as-is, free of charge. For support, you have a few choices:
MagicalRecord是按原樣提供的,免費(fèi)的支持,你有幾個(gè)選擇:

  • Ask your support question on Stackoverflow.com, and tag your question with MagicalRecord. The core team will be notified of your question only if you mark your question with this tag. The general Stack Overflow community is provided the opportunity to answer the question to help you faster, and to reap the reputation points. If the community is unable to answer, we'll try to step in and answer your question.
    在Stackoverflow.com上問(wèn)你的支持問(wèn)題,并與MagicalRecord標(biāo)記你的問(wèn)題厅各。核心團(tuán)隊(duì)將通知你的問(wèn)題只有你和這個(gè)標(biāo)簽標(biāo)記你的問(wèn)題镜撩。一般的堆棧溢出社區(qū)提供機(jī)會(huì)回答問(wèn)題來(lái)幫助你更快,并獲得榮譽(yù)點(diǎn)。如果社區(qū)無(wú)法回答,我們將試圖介入并回答你的問(wèn)題队塘。
  • If you believe you have found a bug in MagicalRecord, please submit a support ticket on the Github Issues page for MagicalRecord. We'll get to them as soon as we can. Please do NOT ask general questions on the issue tracker. Support questions will be closed unanswered.
    如果你相信你在MagicalRecord發(fā)現(xiàn)一個(gè)bug,請(qǐng)?zhí)峤灰粋€(gè)支持機(jī)票在Github MagicalRecord問(wèn)題頁(yè)面袁梗。我們會(huì)盡快。請(qǐng)不要問(wèn)一般問(wèn)題在問(wèn)題跟蹤器憔古。支持將被關(guān)閉的問(wèn)題回答遮怜。
  • For more personal or immediate support, MagicalPanda is available for hire to consult on your project.
    更多的個(gè)人或直接支持,MagicalPanda可供雇傭咨詢您的項(xiàng)目。

**Twitter **推特

Follow @MagicalRecord on twitter to stay up to date with the latest updates relating to MagicalRecord.

在twitter上關(guān)注@MagicalRecord熬夜有關(guān)MagicalRecord最新的更新鸿市。

總結(jié)

不好意思了各位锯梁,可能你們讀者有一些煎熬,沒(méi)辦法焰情,英語(yǔ)水平就這樣陌凳,還要加油。
寫(xiě)了這么多内舟,還是感謝自己堅(jiān)持了下來(lái)合敦。但是事后查看了一些CoreData的相關(guān)文章,發(fā)現(xiàn)有大牛翻譯好的中文文檔验游,而且還是實(shí)時(shí)更新的充岛。不多說(shuō)了,附上中文文檔:MagicalRecord中文文檔

附錄一些不錯(cuò)的DoreData學(xué)習(xí)文章:
小敏的博客coreData詳解
蔣國(guó)綱的技術(shù)博客CoreData教程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耕蝉,一起剝皮案震驚了整個(gè)濱河市崔梗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赔硫,老刑警劉巖炒俱,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異爪膊,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)砸王,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門推盛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人谦铃,你說(shuō)我怎么就攤上這事耘成。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵瘪菌,是天一觀的道長(zhǎng)撒会。 經(jīng)常有香客問(wèn)我,道長(zhǎng)师妙,這世上最難降的妖魔是什么诵肛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮默穴,結(jié)果婚禮上怔檩,老公的妹妹穿的比我還像新娘。我一直安慰自己蓄诽,他們只是感情好薛训,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著仑氛,像睡著了一般乙埃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锯岖,一...
    開(kāi)封第一講書(shū)人閱讀 51,727評(píng)論 1 305
  • 那天膊爪,我揣著相機(jī)與錄音,去河邊找鬼嚎莉。 笑死米酬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的趋箩。 我是一名探鬼主播赃额,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼叫确!你這毒婦竟也來(lái)了跳芳?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤竹勉,失蹤者是張志新(化名)和其女友劉穎飞盆,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體次乓,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吓歇,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了票腰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片城看。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖杏慰,靈堂內(nèi)的尸體忽然破棺而出测柠,到底是詐尸還是另有隱情炼鞠,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布轰胁,位于F島的核電站谒主,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赃阀。R本人自食惡果不足惜霎肯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望凹耙。 院中可真熱鬧姿现,春花似錦、人聲如沸肖抱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)意述。三九已至提佣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間荤崇,已是汗流浹背拌屏。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留术荤,地道東北人倚喂。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像瓣戚,于是被迫代替她去往敵國(guó)和親端圈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容