本文是對 MagicalRecord github上的翻譯
正文:
注意: MagicalRecord 在 ARC 下運作,Core Data 是 ORM 方案,據說帶來的麻煩比好處多,且 Core Data 建立的表沒有主鍵,但對于數據庫沒有性能要求,進行簡單的數據操作完全夠用,能簡化無數的代碼量.
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.
在軟件工程中,對象與數據庫中的記錄實時映射是一種設計模式,在處理關系型數據庫的的軟件中多有出現.這種設計模式被記錄在 Martin Fowler 的<Patterns of Enterprise Application Architecture> 中.被操作對象的接口應該包含增刪改查的方法,基本屬性不多不少的剛好與數據庫中的一條記錄相對應.
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.
實時映射記錄是一種操作數據庫的方式,一個數據庫的表被封裝成一個對象;這個對象中的一個實例會對應著該表中的一條記錄.當創建一個對象時,一條記錄也被插入到表中并保存起來.任何被加載的對象中的屬性信息都從數據庫中讀取;當一個對象更新時,這個數據庫表中對應的記錄也會更新.這個被封裝的類實現了實時操作的方法,且其屬性一一對應于數據庫中表的屬性.
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 靈感來自于簡潔的Ruby語言中 Rails' Active Record 查詢方式. MagicalRecord 這個開源庫的核心思想是:
清除 Core Data 相關的代碼
簡潔的清除,簡單的一行搜索記錄的功能
當然允許使用NSFetchRequest,當存在著復雜的搜索條件時
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!
最簡單的融入MagicalRecord到你的工程的一個方法是使用CocoaPods
添加以下的標示到你的Podfile文件
a.簡單的
pod "MagicalRecord"
b.用CocoaLumberjack記錄器
pod "MagicalRecord/CocoaLumberjack"
在你的項目目錄中,運行更新倉
你現在應該可以添加#import < MagicalRecord / MagicalRecord.h >到任何源文件并開始使用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:
默認情況下,所有的MR_ MagicalRecord提供的類方法是以MR_為前綴。這是(內聯與)根據蘋果的建議而不是創建不加裝飾的分類方法來避免命名沖突。
如果你喜歡,你可以包括下列使用短的標題,沒有前綴的分類方法:
#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、你需要添加這些入口到你的目標的objective - c橋接頭文件。
一旦你包括標題,在你設置/使用MagicalRecord:之前你應該喚起+[MagicalRecord enableShorthandMethods]類方法
- (void)theMethodWhereYouSetupMagicalRecord
{
[MagicalRecord enableShorthandMethods];
// Setup MagicalRecord as per usual 設置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.
請注意,我們不支持這個功能。如果它不工作,請文件描述問題,當我們可能的時候我們會解決它。
- [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.
首先,導入MagicalRecord.h頭文件在您的項目的pch文件。這將允許全局包括所有需要的頭文件。
If you're using CocoaPods or MagicalRecord.framework, your import should look like:
如果你使用CocoaPods或MagicalRecord框架,你的導入應該看起來像:
// 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:
否則,如果你已經直接地添加MagicalRecord的源文件到你的 objective - c項目中,你的導入應該是:
#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:
接下來,在您的應用程序委托的一些地方,無論是- applicationDidFinishLaunching:withOptions:方法,或-awakefromnib,使用以下設置的一個調用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".
每次調用所有實例化各個核心數據棧之一,并為這些實例提供了getter和setter方法。這些眾所周知的實例MagicalRecord,被認為是“默認的”。
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!
當使用默認SQLite數據存儲用DEBUG調試標記設置,改變你的模型沒有創建一個新的模型版本的時候將導致MagicalRecord刪除舊的存儲和自動創建一個新的。這可以節省大量時間,每次你改變你的數據模型就不再需要卸載和重新安裝應用程序。請確保不要將你的應用程序與調試功能連接:刪除應用程序的數據而沒有告訴用戶它是非常糟糕的!
Before your app exits, you should call +cleanUp class method:
在程序退出之前,你應該調用+ 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后,拆除我們的自定義錯誤處理和設置所有的由MagicalRecord創建的核心數據堆棧為零。
>**iCloud-enabled Persistent Stores iCloud功能的持久存儲**
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:
利用蘋果的iCloud核心數據同步,使用以下設置方法之一 代替 在前一節中列出的標準方法:
>```
>+ (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).
要了解進一步的細節,請參閱蘋果的iCloud編程指南的核心數據。
>**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):
如果您管理多個iCloud-enabled商店,我們建議您使用一個較長的設置方法,允許您指定自己的contentNameKey。較短的設置方法自動生成基于應用程序的包標識符(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 工作與管理對象上下文**
>**Creating New Contexts 創建新環境**
A variety of simple class methods are provided to help you create new contexts:
提供各種簡單的類方法來幫助您創建新的上下文:
- **+[NSManagedObjectContext MR_newContext]**: Sets the default context as it's parent context. Has a concurrency type of NSPrivateQueueConcurrencyType.
設置默認上下文作為它的父上下文。有一個并發的NSPrivateQueueConcurrencyType類型。
- **+[NSManagedObjectContext MR_newMainQueueContext]**: Has a concurrency type of NSMainQueueConcurrencyType.
一種并發NSMainQueueConcurrencyType類型。
- **+[NSManagedObjectContext MR_newPrivateQueueContext]**: Has a concurrency type of NSPrivateQueueConcurrencyType.
一種并發NSPrivateQueueConcurrencyType 類型。
- **+[NSManagedObjectContext MR_newContextWithParent:…]**: Allows you to specify the parent context that will be set. Has a concurrency type of NSPrivateQueueConcurrencyType.
允許您指定將被設置的父上下文。有一個并發的NSPrivateQueueConcurrencyType類型。
- **+[NSManagedObjectContext MR_newContextWithStoreCoordinator:…]**: Allows you to specify the persistent store coordinator for the new context. Has a concurrency type of NSPrivateQueueConcurrencyType.
允許您指定持久性存儲協調員作為新的上下文。有一個并發的NSPrivateQueueConcurrencyType類型。
>**The Default Context 默認的上下文**
When working with Core Data, you will regularly deal with two main objects: NSManagedObject and NSManagedObjectContext.
使用Core Data時,您將定期處理兩個主要對象: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提供了一個簡單的類方法來檢索一個默認的可以始終在你的App使用的NSManagedObjectContext,。這種上下文運行在主線程,且十分的簡單,單線程應用在程序中。
To access the default context, call: 訪問默認上下文,使用:
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.
在使用一個上下文的任何方法里,這種上下文將貫穿整個MagicalRecord使用,但并不能驗證特定管理對象上下文參數。
If you need to create a new managed object context for use in non-main threads, use the following method:
如果您需要創建一個新的管理對象上下文用于非主線程,使用下面的方法:
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.
這將會創建一個新的管理對象上下文,它有相同的對象模型和持久化存儲作為默認上下文,但是是安全的使用在另一個線程上。它會自動設置默認上下文作為父上下文。
If you'd like to make your myNewContext instance the default for all fetch requests, use the following class method:
如果你想讓你的myNewContext實例默認的為所有獲取請求,使用以下類方法:
[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.
注意:強烈建議默認上下文被創建且使用管理對象上下文設置在主線程用并發NSMainQueueConcurrencyType類型。
>**Performing Work on Background Threads 在后臺線程執行工作**
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提供方法來設置和使用上下文在后臺線程中使用。后臺操作受UIView動畫塊方法,有一些細微的差別:
? The block in which you make changes to your entities will never be executed on the main thread.
你改變實體的塊永遠不會在主線程上執行。
? A single NSManagedObjectContext is provided for you within these blocks.
單個NSManagedObjectContext為你提供在這些街區。
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:
例如,如果我們有實體的人,我們需要設置firstName和lastName字段,這是如何使用MagicalRecord設置背景為您的使用環境:
>```
>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.
在這種方法中,指定的塊為您提供適當的上下文來執行您的操作,你不需要擔心設置上下文,以便它告訴默認上下文,就完成了,而且應該更新,因為修改另一個線程上執行。
To perform an action after this save block is completed, you can fill in a completion block:
塊后執行一個動作完成后,你可以填寫完成塊:
>```
>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.
這個完成塊呼吁主線程(隊列),所以這也是安全的觸發UI更新。
- [Creating Entities](https://github.com/magicalpanda/MagicalRecord/blob/master/Docs/Creating-Entities.md)
>**Creating Entities 創建實體**
To create and insert a new instance of an Entity in the default context, you can use:
創建和插入一個新實例的實體在缺省情況下,您可以使用:
Person *myPerson = [Person MR_createEntity];```
To create and insert an entity into specific context:
創建和插入一個實體特定上下文:
Person *myPerson = [Person MR_createEntityInContext:otherContext];```
- [Deleting Entities](https://github.com/magicalpanda/MagicalRecord/blob/master/Docs/Deleting-Entities.md)
>**Deleting Entities 刪除實體**
To delete a single entity in the default context:
刪除一個單一的實體在默認上下文:
[myPerson MR_deleteEntity];```
To delete the entity from a specific context:
刪除實體從一個特定的背景:
[myPerson MR_deleteEntityInContext:otherContext];```
To truncate all entities from the default context:
從默認的上下文截斷所有實體:
[Person MR_truncateAll];```
To truncate all entities in a specific context:
截斷所有實體在一個特定的背景:
[Person MR_truncateAllInContext:otherContext];```
- [Fetching Entities](https://github.com/magicalpanda/MagicalRecord/blob/master/Docs/Fetching-Entities.md)
>###**Fetching Entities 獲取實體**
>**Basic Finding 基本的發現**
Most methods in MagicalRecord return an NSArray of results.
大多數方法MagicalRecord NSArray返回的結果。
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:
作為一個例子,如果你有一個Person實體相關部門實體(正如在很多蘋果的核心數據的例子),你可以從持久存儲中檢索所有人的實體使用以下方法:
NSArray *people = [Person MR_findAll];```
To return the same entities sorted by a specific attribute:
返回相同的實體按特定的屬性:
NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName"
ascending:YES];```
To return the entities sorted by multiple attributes:
返回的實體排序由多個屬性:
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:
返回結果按多個屬性具有不同的值。如果你不為任何屬性提供一個值,它將默認為你已經在你的模型:
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:
如果你有一個獨特的檢索方式從數據存儲一個對象(比如一個標識符屬性),您可以使用以下方法:
Person *person = [Person MR_findFirstByAttribute:@"FirstName"
withValue:@"Forrest"];```
>**Advanced Finding 先進的發現**
If you want to be more specific with your search, you can use a predicate:
如果你想要更具體的和你的搜索,你可以使用一個謂詞:
NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", @[dept1, dept2]];
NSArray *people = [Person MR_findAllWithPredicate:peopleFilter];```
Returning an NSFetchRequest 返回一個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.
每個一行調用,一個NSFetchRequest NSSortDescriptors創建的任何分類標準。
>**Customizing the Request 自定義請求**
>```
>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 找到實體的數量**
You can also perform a count of all entities of a specific type in your persistent store:
您還可以執行特定類型的所有實體的計算你的持久性存儲:
NSNumber *count = [Person MR_numberOfEntities];```
Or, if you're looking for a count of entities based on a predicate or some filter:
或者,如果你正在尋找一個計數的實體基于謂詞或一些過濾器:
NSNumber *count = [Person MR_numberOfEntitiesWithPredicate:...];```
There are also complementary methods which return NSUInteger rather than NSNumber instances:
也有互補的方法,返回了NSUInteger而不是NSNumber實例:
- (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 發現實體在一個特定的上下文**
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:
所有發現,取回,并要求有它的方法:方法參數,允許您指定管理對象上下文你想查詢:
>```
>NSArray *peopleFromAnotherContext = [Person MR_findAllInContext:someOtherContext];
>Person *personFromContext = [Person MR_findFirstByAttribute:@"lastName"
withValue:@"Gump"
inContext:someOtherContext];
>NSUInteger count = [Person MR_numberOfEntitiesWithContext:someOtherContext];
Saving Entities 保存實體
When should I save? 當我要保存嗎?
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.
一般來說,應用程序應該保存到它的持久性存儲(s)當數據更改的時候。一些應用程序選擇節省應用程序終止,然而這個應該是不必要的在大多數情況下——事實上,如果你只保存應用程序終止時,你面臨著丟失數據!如果你的應用程序崩潰,會發生什么?用戶將失去他們的所有更改,這是一個可怕的經歷,且容易避免。
If you find that saving is taking a long time, there are a couple of things you should consider doing:
如果你發現保存很長一段時間,有幾件事情你應該考慮做:
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:
保存在一個后臺線程:MagicalRecord提供了一個簡單,干凈的API更改你的實體和隨后保存在一個后臺線程,例如:
[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.
把任務分解成較小的保存:任務導入大量數據應該被分解成小塊。沒有統一的規則你應該節約多少數據,所以你需要測量應用程序的性能使用像蘋果這樣的工具的工具和適當調整。
Handling Long-running Saves 處理長期保存
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應用程序終止時,它給出一個小機會整理并保存任何數據到磁盤。如果你知道一個保存操作可能需要一段時間,最好的方法是請求的擴展應用程序的過期,像這樣:
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一定要仔細閱讀文檔,不當或不必要的擴展應用程序的生命周期可能會贏得你的應用程序從應用程序商店拒絕。
>**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)和后,應用午睡會使您的應用程序充當雖然有效地終止時的背景。如果你知道一個保存操作可能需要一段時間,最好的方法是暫時禁用自動和突然終止(假設您的應用程序支持這些特性):
>```
>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實施這種方法在你的應用程序。
Changes to saving in MagicalRecord 2.3.0 變化在MagicalRecord tripwire儲蓄
Context For Current Thread Deprecation 當前線程上下文棄用
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的早期版本中,我們提供了方法來檢索管理對象上下文的線程的方法被稱為。不幸的是,它是不可能返回當前執行的線程的上下文以可靠的方式了。中央調度(GCD)毫無保證隊列將單個線程上執行,和我們的方法是基于老NSThread API雖然CoreData轉換到使用腎小球囊性腎病。有關詳細信息,請參閱掃羅的文章“為什么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,我們繼續使用+ MR_contextForCurrentThread內部在一些地方保持兼容老版本。這些方法被棄用,你會警告說如果你使用它們。
In particular, do not use +MR_contextForCurrentThread from within any of the +[MagicalRecord saveWithBlock:…] methods — the returned context may not be correct!
特別是,不使用+從內部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:
如果你想開始準備改變現在,請使用方法的變體,接受“上下文”參數,并使用上下文傳遞給你的+(MagicalRecord saveWithBlock:…)方法。而不是:
[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntity];
// …
}];
You should now use:
現在,您應該使用:
[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發布時,當前線程的上下文方法完全將被刪除。方法,不接受“上下文”參數將使用默認上下文默認的堆棧-請參閱MagicalRecord 3.0發行說明了解更多細節。
Changes to saving in MagicalRecord 2.2.0 改變在MagicalRecord 2.2.0儲蓄
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中,儲蓄的api是修改后的表現更加一致,并遵循命名模式出現在核心數據。廣泛的工作已經進入添加自動化測試,確保保存方法(新和棄用)繼續工作如預期在未來的更新。
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已經暫時恢復到原始狀態的運行在當前線程同步,并保存到持久性存儲。然而,MR_save方法標記為過時的,將被刪除的下一個主要版本MagicalRecord(版本3.0)。您應該使用MR_saveToPersistentStoreAndWait如果你想同樣的行為在未來版本的庫。
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 導入數據
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.
我們正在更新這個文檔,謝謝你的耐心。目前,請參考導入數據很容易在可可是我的女朋友。本文基于掃羅的工作在原來的文章。
MagicalRecord Team
MagicalRecord團隊
MagicalRecord can help import data from standard NSObject instances such as NSArray and NSDictionary directly into your Core Data store.
MagicalRecord可以幫助導入數據從標準如NSArray和NSDictionary NSObject實例直接進入你的核心數據存儲。
It's a two step process to import data from an external source into your persistent store using MagicalRecord:
這是一個兩步的過程,從外部源數據導入到持久性存儲使用MagicalRecord:
- Define how the data you're importing maps to your store using your data model (it's pretty much codeless!)
定義如何將數據導入映射到你的商店使用您的數據模型(幾乎無代碼!) - Perform the data import
執行數據導入
Define Your Import 定義您的進口
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.
從外部數據源的數據可以廣泛的變量在質量和結構,所以我們已經盡力使MagicalRecord的進口流程靈活。
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可以導入數據從任何鍵值編碼(現有的)兼容的對象。我們通常發現人們使用NSArray和NSDictionary實例,但它工作得很好與任何現有的兼容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數據建模工具的“用戶信息”值允許進口的配置選項和映射可能不需要修改任何代碼。
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附在每一個實體,屬性和關系數據模型,可以通過用戶信息訪問方法NSEntityDescription實例。
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的數據建模工具給你訪問這個字典通過數據模型檢查器的“用戶信息”。在編輯一個數據模型時,您可以使用Xcode的菜單,打開這個檢查員視圖>工具>顯示數據模型檢查器,或按??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.
默認情況下,MagicalRecord會自動嘗試匹配鍵的屬性和關系名稱您導入的數據。如果一個屬性或關系名稱在您的數據模型匹配的關鍵,你不需要做任何事情——價值將自動導入的關鍵。
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.
舉個例子,如果一個屬性對一個實體的名字“firstName”,MagicalRecord假設關鍵數據的導入也將一個關鍵的“firstName”——如果是這樣,你的實體firstName屬性的值將被設置為firstName的關鍵數據。
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.
往往,鑰匙和結構數據的導入不會匹配您的實體的屬性和關系。在這種情況下,您將需要告訴MagicalRecord如何導入數據的鍵映射到正確的屬性或關系數據模型。
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:
我們每三個關鍵對象的處理核心數據——實體,屬性和關系,選項可能通過用戶信息需要指定鍵:
Attributes
Attributes.png
Entities
Entities.png
Relationships
Relationships.png
Importing Objects 進口物品
To import data into your store using MagicalRecord, you need to know two things:
使用MagicalRecord數據導入到你的店鋪,你需要知道兩件事:
- 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.
你導入的格式數據,以及它如何MagicalRecord背后的基本理念的導入,你知道實體應該導入的數據,所以你寫一行代碼將這個實體的數據導入。有一些選項來啟動導入過程。
To automatically create a new instance from the object, you can use the following, shorter approach:
自動創建一個新實例的對象,您可以使用以下,較短的方法:
NSDictionary *contactInfo = // Result from JSON parser or some other source
Person *importedPerson = [Person MR_importFromObject:contactInfo];
You can also use a two-stage approach:
您還可以使用一個兩階段的方法:
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.
兩階段方法可以幫助如果你想通過覆蓋更新現有對象的屬性。
+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:將尋找現有對象的基礎上,查找配置值(見relatedByAttribute attributeNameID)。也注意到此前范式的建立進口可可豆中的鍵值對列表,以及導入數據的安全方法。
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:類方法提供了一個包裝使用前面提到的-MR_importValuesForKeysWithObject:創建一個新的對象實例方法,并返回新創建的對象數據。
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:
注意的是,這兩種方法的一個關鍵項是同步的。雖然一些進口將比別人花費更多的時間,它仍然是高度建議執行所有進口的背景,以便不影響用戶交互。正如前面所討論的那樣,MagicalRecord提供了一個方便的API來使用后臺線程更易于管理:
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *)localContext {
Person *importedPerson = [Person MR_importFromObject:personRecord inContext:localContext];
}];```
>**Importing Arrays 輸入數組**
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.
公共的數據是使用JSON數組,或者你導入一個大型的單一類型的數據列表。進口的細節中照顧這樣一個列表+ 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:也是同步的,所以對于背景導入,使用前面提到的輔助方法用于執行塊的背景。
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.
如果你導入數據完全匹配你的核心數據模型,然后閱讀不再因為前面提到的方法都是需要你的數據導入到你的核心數據存儲。最喜歡的,但是,如果您的數據小怪癖和輕微的偏差,然后繼續讀下去,當我們穿過的一些特性MagicalRecord會幫助你處理一些常見的偏差。
>**Best Practice 最佳實踐**
>**Handling Bad Data When Importing 處理錯誤數據在導入**
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會返回數據格式不一致或值。處理這個問題的最好方法是使用進口的方法在你的實體類。提供有三種:

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.
一般來說,如果您的數據是壞你要解決什么導入后一直嘗試導入任何值。
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:
一個常見的場景是進口JSON數據,數字字符串常常被誤解為一個實際的數字。如果你想確保一個值是進口作為一個字符串,你可以做以下幾點:
>```
>@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 刪除本地導入更新記錄**
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.
有時你會想要確保后續導入操作不僅更新也刪除本地記錄,不包括作為遠程數據集的一部分。為此,獲取所有本地記錄不包含在此更新通過relatedByAttribute在下面的例子中(id)和刪除它們之前立即導入新數據集。
>```
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
如果你也想要確保在這更新相關記錄被刪除,您可以使用類似的邏輯willImport如上,但實現它:方法的人
>```
>@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日志建立在與核心數據的交互。當錯誤發生在抓取或保存數據時,這些錯誤捕獲和(如果你使他們)登錄到控制臺。
Logging is configured to output debugging messages (MagicalRecordLoggingLevelDebug) by default in debug builds, and will output error messages (MagicalRecordLoggingLevelError) in release builds.
日志配置為默認輸出調試信息(MagicalRecordLoggingLevelDebug)在調試構建,并將輸出錯誤消息(MagicalRecordLoggingLevelError)發布構建。
Logging can be configured by calling [MagicalRecord setLoggingLevel:]; using one of the predefined logging levels:
日志可以通過調用配置(MagicalRecord setLoggingLevel:];使用一個預定義的日志記錄級別:
? MagicalRecordLogLevelOff: Don't log anything 不要什么日志
? MagicalRecordLoggingLevelError: Log all errors 記錄所有錯誤
? MagicalRecordLoggingLevelWarn: Log warnings and errors 日志警告和錯誤
? MagicalRecordLoggingLevelInfo: Log informative, warning and error messages 日志信息,警告和錯誤消息
? MagicalRecordLoggingLevelDebug: Log all debug, informative, warning and error messages 記錄所有調試信息,警告和錯誤消息
? MagicalRecordLoggingLevelVerbose: Log verbose diagnostic, informative, warning and error messages 日志詳細的診斷信息,警告和錯誤消息
The logging level defaults to MagicalRecordLoggingLevelWarn.
MagicalRecordLoggingLevelWarn日志級別默認值。
>**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的日志。所有你需要做的是確保進口CocoaLumberjack進口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.
對大多數人來說這應該是不必要的。將日志級別設置為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,快速檢查可能只要一個日志調用執行。如果您絕對需要禁用日志記錄,您將需要編譯MagicalRecord時定義如下:
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.
請注意,這只會工作如果你MagicalRecord源添加到自己的項目。您還可以添加這個MagicalRecord項目的OTHER_CFLAGS -DMR_LOGGING_DISABLED = 1。
Resources 資源
The following articles highlight how to install and use aspects of MagicalRecord:
下面的文章強調如何MagicalRecord的安裝和使用方面:
How to make Programming with Core Data Pleasant 如何使編程與核心數據愉快嗎
Using Core Data with MagicalRecord 與MagicalRecord使用核心數據
Super Happy Easy Fetching in Core Data 超級快樂在核心數據容易獲取
Core Data and Threads, without the Headache 核心數據和線程,沒有頭痛
Unit Testing with Core Data 單元測試與核心數據
**Support **支持
MagicalRecord is provided as-is, free of charge. For support, you have a few choices:
MagicalRecord是按原樣提供的,免費的支持,你有幾個選擇:
- 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上問你的支持問題,并與MagicalRecord標記你的問題。核心團隊將通知你的問題只有你和這個標簽標記你的問題。一般的堆棧溢出社區提供機會回答問題來幫助你更快,并獲得榮譽點。如果社區無法回答,我們將試圖介入并回答你的問題。 - 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發現一個bug,請提交一個支持機票在Github MagicalRecord問題頁面。我們會盡快。請不要問一般問題在問題跟蹤器。支持將被關閉的問題回答。 - For more personal or immediate support, MagicalPanda is available for hire to consult on your project.
更多的個人或直接支持,MagicalPanda可供雇傭咨詢您的項目。
**Twitter **推特
Follow @MagicalRecord on twitter to stay up to date with the latest updates relating to MagicalRecord.
在twitter上關注@MagicalRecord熬夜有關MagicalRecord最新的更新。
總結
不好意思了各位,可能你們讀者有一些煎熬,沒辦法,英語水平就這樣,還要加油。
寫了這么多,還是感謝自己堅持了下來。但是事后查看了一些CoreData的相關文章,發現有大牛翻譯好的中文文檔,而且還是實時更新的。不多說了,附上中文文檔:MagicalRecord中文文檔
附錄一些不錯的DoreData學習文章:
小敏的博客 之 coreData詳解
蔣國綱的技術博客 之 CoreData教程