走進Realm的世界

Realm是什么

Realm是由Y Combinator公司孵化出來的一款可以用于iOS(同樣適用于Swift&Objective-C)和Android的跨平臺移動數(shù)據(jù)庫示血。歷經(jīng)幾年才打造出來,為了徹底解決性能問題娶聘,核心數(shù)據(jù)引擎用C++打造,并不是建立在SQLite之上的ORM薪伏,所以Realm相比SQLite和CoreData而言更快、更好爹殊、更容易去使用和完成數(shù)據(jù)庫的操作花費更少的代碼蜕乡。它旨在取代CoredData和sqlite,它不是對coreData的簡單封裝、相反的梗夸,Realm它使用了它自己的一套持久化存儲引擎异希。而且Realm是完全免費的,這不僅讓它變得更加的流行也使開發(fā)者使用起來沒有任何限制绒瘦。

Realm的特點

Realm以難以令人置信的快速和易用讓開發(fā)者能夠用僅僅幾行代碼完成你所需要的一切功能。它旨在打造讓用戶得在到移動領域離線時的最好體驗扣癣,我整理了Realm具有的如下特點:

  • 易安裝:正如你在將要看到的使用Realm工作惰帽。安裝Realm就像你想象中一樣簡單。在Cocoapods中使用簡單命令父虑,你就可以使用Realm工作该酗。
  • 速度上:Realm是令人無法想象的快速使用數(shù)據(jù)庫工作的庫。Realm比SQLite和CoreData更快士嚎,這里的數(shù)據(jù)就是最好的證明呜魄。
  • 跨平臺:Realm數(shù)據(jù)庫文件能夠跨平臺和可以同時在iOS和Andriod使用。無論你是使用Java, Objective-C, or Swift莱衩,你都可以使用你的高級模型爵嗅。
  • 可擴展性:在開發(fā)你的移動App特別是如果你的應用程序涉及到大量的用戶和大量的記錄時,具有良好的可擴展性是非常重要的笨蚁。
  • 好的文檔&支持:Realm團隊提供了可讀的睹晒,非常有組織的并且豐富的文檔。如果你遇到什么問題通過Twitter括细、GitHub或者Stackoverflow與他們交流伪很。
  • 可靠性:Realm已經(jīng)被巨頭公司使用在他們的移動App中,像Pinterest, Dubsmash, and Hipmunk奋单。
  • 免費性:使用Realm的所有功能都是免費的锉试。
  • 懶加載:只有當你真正訪問對象的值時候才真正從磁盤中加載進來。

必備條件

  • iOS7及以后, OS X 10.9及以后览濒。
  • 至少Xcode7.3及以后呆盖。
  • Realm針對iOS分為兩部分,一個是Swift版本匾七,一個是Objective-C版本絮短。

Realm安裝

  • 動態(tài)Framework庫。直接下載最新Realm的release版本昨忆,拖入項目工程中即可丁频。
  • CocoaPods管理工具。使用CocoaPods0.39版本以及上。
  • Carthage管理工具席里。使用Carthage 0.17.0版本及以上叔磷。
  • 靜態(tài)Framework庫。直接下載最新Realm的release版本奖磁,拖入項目工程中即可改基。

(注意:本文將重點講解使用CocoaPods的方式安裝Realm到項目中)

配置Xcode和所需的工具

在配置Xcode項目之前,請確保你的電腦上已經(jīng)安裝了CocoaPods咖为,因為我們會使用CocoaPods在項目中安裝Realm秕狰。如果你不熟悉CocoaPods,你可以查看給你的網(wǎng)上的相關教程躁染。

現(xiàn)在創(chuàng)建一個新的工程鸣哀,選擇"Single View Application",命名為RealmDemo或者任何你想的名稱吞彤。請確保創(chuàng)建的項目是Objective-C語言∥页模現(xiàn)在在終端打開你的項目目錄并執(zhí)行如下的CocoaPods命令:

Pod init

然后,使用Xcode打開Podfile文件饰恕,向其中添加如下內(nèi)容:

realm-podfile.png

接下來執(zhí)行Pod install命令去下載Realm安裝到項目中挠羔。完成之后,你將看到新的Xcode項目的workspace在Podfile文件被生成埋嵌。請打開Xcode的RealmDemo.xworkspace和不要打開xcodeproj破加。打開workspace之后,你將看到Pod相關文件已經(jīng)被集成進去了雹嗦。

現(xiàn)在Xcode已經(jīng)準備好可以使用Realm工作了拌喉,但是我們還將需要安裝如下工具為的是讓我們使用Realm更輕松,容易俐银。

在Xcode中安裝Realm插件(僅僅用于Xcode8以下版本)

Realm團隊已經(jīng)提供了非常有用的Xcode插件尿背,它將被使用在生成Realm的模型。為了安裝插件捶惜,我們使用Alcatraz.對于那些不了解什么是Alcatraz的人來說,可以自行去搜索下田藐,Alcatraz真的非常好用。為了安裝Alcatraz需要通過以下終端中的命令行并且重啟你的Xcode吱七。

curl -fsSL https://raw.githubusercontent.com/supermarin/Alcatraz/master/Scripts/install.sh | sh

之后在Xcode中汽久,選擇Window,就可以看到下拉列表中的Package Manager選項,就表明已經(jīng)安裝成功踊餐。
在Xcode彈出窗口中選擇需要的插件或者模板景醇,在搜索框中你可以搜索任何插件或者各種各樣的模板去自定義你的Xcode。在搜索框中輸入"Realm"和"RealmPlugin"插件將顯示出來吝岭,點擊進行安裝三痰。

Realm瀏覽器

除了以上的工具和插件之外吧寺,還有一個就是Realm瀏覽器。這個瀏覽器可以幫助你去閱讀和編輯你的.realm數(shù)據(jù)庫文件散劫。這些文件是在你的應用程序中被創(chuàng)建出來的稚机,它包含了關于數(shù)據(jù)庫表中實體、屬性和記錄的信息获搏。目前直接在Mac App Store中搜索Realm Browser進行下載即可赖条。下載完成后,打開Realm瀏覽器選擇Tools-> Generate demo database常熙。它將為你生成測試數(shù)據(jù)庫文件和你可以打開它看到里面的數(shù)據(jù)纬乍。當你打開你的demo database時你應該看到

browser.png

正如你看到的Class RealmTestClass1,它有1000個記錄和它展示了不同的列數(shù)據(jù)。接下來我們將討論Realm模型支持的屬性類型裸卫。

Realm的數(shù)據(jù)庫創(chuàng)建

目前Realm提供了3種方式創(chuàng)建數(shù)據(jù)庫對象蕾额,一種是存儲在默認路徑下的數(shù)據(jù)庫,一種是我們可以指定自己指定數(shù)據(jù)庫文件的存儲路徑和只讀屬性彼城,還有一種可以使用內(nèi)存數(shù)據(jù)庫。

  • 默認Realm數(shù)據(jù)庫
RLMRealm *realm = [RLMRealm defaultRealm];
  • 自定義數(shù)據(jù)庫(名稱退个、路徑)
//注意:新版本中關于配置Relam的文件路徑包括名稱等等都是在RLMRealmConfiguration對象中完成募壕。
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
// Use the default directory, but replace the filename with the username
 config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent]
                      URLByAppendingPathComponent:username]
                      URLByAppendingPathExtension:@"realm"];
// Set this as the configuration used for the default Realm
  [RLMRealmConfiguration setDefaultConfiguration:config];

或者是

NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *dbPath = [docPath stringByAppendingPathComponent:@"guojie.realm"];
RLMRealm *realm1 = [RLMRealm realmWithURL:url];

當然了,RLMRealmConfiguration對象中還可以設置是否只讀數(shù)據(jù)庫

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
// Get the URL to the bundled file
config.fileURL = [[NSBundle mainBundle] URLForResource:@"MyBundledData" withExtension:@"realm"];
// Open the file in read-only mode as application bundles are not writeable
config.readOnly = YES;
  • 內(nèi)存數(shù)據(jù)庫
    正常的Realm數(shù)據(jù)庫是存儲在硬盤上的语盈,但是我們可以通過在RLMRealmConfiguration中設置inMemoryIdentifier屬性來創(chuàng)建一個內(nèi)存數(shù)據(jù)庫舱馅。
RLMRealmConfiguration *cfg = [RLMRealmConfiguration defaultConfiguration];
cfg.inMemoryIdentifier = @"test";
RLMRealm *realm = [RLMRealm realmWithConfiguration:cfg error:nil];

注意:內(nèi)存數(shù)據(jù)庫在每次程序退出時不會保存數(shù)據(jù)。如果某個內(nèi)存Realm實例沒有被引用刀荒,所有的數(shù)據(jù)在實例對象釋放的適合也會被釋放代嗤。建議你在app中用強引用來鉗制所有新建的內(nèi)存Realm數(shù)據(jù)庫實例。

Realm的構建數(shù)據(jù)模型

Realm的數(shù)據(jù)模型是用傳統(tǒng)的 Objective-C 接口(interface)和屬性(@property)定義的缠借。 只要定義 RLMObject的一個子類或者一個現(xiàn)成的模型類干毅,你就能輕松創(chuàng)建一個Realm的數(shù)據(jù)模型對象。Realm模型對象和其他的Objective-C的功能很相似–你可以給它們添加你自己的方法和protocol然后和其他的對象一樣使用泼返。 唯一的限制就是從它們被創(chuàng)建開始硝逢,只能在一個進程中被使用。如果你已經(jīng)安裝了Xcode Plugin(Xcode版本<8.0)绅喉,你將直接很方便在Xcode中的New File對話框中選擇Realm Model Object類的模板創(chuàng)建渠鸽。你可以用它來創(chuàng)建interface和implementation文件。廢話不說柴罐,直接上代碼徽缚。

現(xiàn)在一起來使用Xcode中的Realmh插件去創(chuàng)建Realm類。打開Xcode和創(chuàng)建新文件革屠。在右邊框中選擇Realm:

然后選擇名稱為Dog類名的Objective-C文件≡涫裕現(xiàn)在你應該看到如下信息:

Dog_objcetive-c.png

用一個Dog對象來表示一條小狗排宰,緊接向類中添加屬性。然后類在添加屬性之后向如下這樣:

  • Dog.h
@interface Dog : RLMObject
/** 名字 */
@property (nonatomic, copy) NSString *name;
/** 年齡 */
@property (nonatomic, assign) NSInteger age;
/** 品種 */
@property (nonatomic, copy) NSString *type;
RLM_ARRAY_TYPE(Dog)
@end
  • Dog.m
@implementation Dog

/**
 設置主鍵
 */
+ (NSString *)primaryKey{
    return @"numId";
}
/**
 添加索引的屬性
 */
+ (NSArray<NSString *> *)indexedProperties{
    return @[@"name"];
}
/**
 添加默認值
 */
+ (NSDictionary *)defaultPropertyValues{
    return @{@"type":@"taidi"
             };
}
@end

說明:

  1. Realm支持的屬性類型如下:BOOL, bool, int, NSInteger, long, float, double, CGFloat, NSString, NSDate 和 NSData红省。
  2. 你可以使用RLMArray<Object>和RLMObject來模擬對一或?qū)Χ嗟年P系(Realm也支持RLMObject繼承)
  3. Realm忽略了Objective-C的property attributes(如nonatomic, atomic, strong, copy, weak 等等)额各。 所以,推薦在創(chuàng)建模型的時候不要使用任何的property attributes吧恃。但是虾啦,假如你設置了,這些attributes會一直生效直到RLMObject被寫入realm數(shù)據(jù)庫痕寓。
  4. 定義了RLM_ARRAY_TYPE(Dog) 這個宏表示支持RLMArray<Dog>該屬性
  5. 另外Realm提供了以下幾個方法供對屬性進行自定義:
    • (NSArray<NSString *> *)indexedProperties;: 可以被重寫來來提供特定屬性(property)的屬性值(attrbutes)例如某個屬性值要添加索引傲醉。
    • (nullable NSDictionary *)defaultPropertyValue;: 為新建的對象屬性提供默認值。
    • (nullable NSString *)primaryKey;: 可以被重寫來設置模型的主鍵呻率。定義主鍵可以提高效率并且確保唯一性硬毕。
    • (nullable NSArray *)ignoredProperties;:可以被重寫來防止Realm存儲模型屬性。
    • (void)transactionWithBlock:(attribute((noescape)) void(^)(void))block;:自動更新對象數(shù)據(jù)礼仗。
    • (NSArray<NSString *> *)requiredProperties;可選屬性

Realm的數(shù)據(jù)增刪改查

存儲數(shù)據(jù)

(1).創(chuàng)建Dog對象吐咳,依次設置各個屬性

    ```Objective-C
    Dog *myDog = [[Dog alloc]init];
    myDog.numId = @"1";
    myDog.name  = @"haha";
    myDog.age   = 10;
    myDog.type  = @"taidi";
    ```

(2).使用字典創(chuàng)建Dog對象

    ```Objective-C
    Dog *myDog2 = [[Dog alloc]initWithValue:@{@"numId":@"2",
                                             @"name" :@"xiaoxiao",
                                             @"age"  :@11,
                                             @"type" :@"heibei"
                                          }];
    ```

(3).使用數(shù)組創(chuàng)建Dog對象

    ```Objective-C
    Dog *myDog3 = [[Dog alloc]initWithValue:@[@"3",@"小小",@12,@"smy"]];
    ```

(4).除此之外,還支持嵌套的對象

如果在對象的屬性中有RLMObjects對象或者RLMArrays對象元践,在這種情況下當你使用字典或者數(shù)組途徑創(chuàng)建對象時韭脊,你就可以使用數(shù)組或者字典對象替換屬性來表示它的屬性。例如下面的嵌套對象例子:

// Instead of using already existing dogs...
Person *person1 = [[Person alloc] initWithValue:@[@"Jane", @30, @[aDog, anotherDog]]];

// ...we can create them inline
Person *person2 = [[Person alloc] initWithValue:@[@"Jane", @30, @[@[@"Buster", @5],
                                                                  @[@"Buddy", @6]]]];

說明:

1. 最明顯的是使用指定的初始化程序創(chuàng)建一個對象单旁。注意被設置為必須的屬性在被添加之前一定要被設置值沪羔。
2. 對象可以通過傳入與屬性名稱一樣的字典Key和Values來創(chuàng)建。
3. 最后象浑,對象可以使用數(shù)組創(chuàng)建蔫饰,需要注意的是在數(shù)組中值的順序必須跟Model中相應屬性順序保持一致。
4. 需要注意的是: RLMArray僅僅只能包含RLMObject對象愉豺,而不包括基本數(shù)據(jù)類型例如NSString篓吁。

(5).存儲數(shù)據(jù)到Realm中

RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
[realm addObject:myDog];
[realm commitWriteTransaction];

請注意:當你同時執(zhí)行多個寫入操作時,它們將會阻礙執(zhí)行的所在線程蚪拦。所以你應該考慮在單獨的線程中處理而不是UI線程越除。另一個就是,當你在執(zhí)行寫入操作時外盯,讀取操作不會被阻塞摘盆。這一點是很有用的,因為你的App可以執(zhí)行許多讀取操作時在后臺同一時間寫入事務可能也會在后臺執(zhí)行中饱苟。

刪除數(shù)據(jù)

  • 刪除指定的數(shù)據(jù):
- (void)deleteObject:(RLMObject *)object;
  • 刪除一組數(shù)據(jù):
- (void)deleteObjects:(id)array;
  • 刪除全部數(shù)據(jù):
- (void)deleteAllObjects;

修改數(shù)據(jù)

如果該條數(shù)據(jù)不存在則會新家一條數(shù)據(jù)孩擂。

  • 針對單條數(shù)據(jù)進行的修改或新增:
- (void)addOrUpdateObject:(RLMObject *)object;
  • 針對一組數(shù)據(jù)的修改或新增:
- (void)addOrUpdateObjectsFromArray:(id)array;
  • 針對帶有主鍵的數(shù)據(jù)修改或新增

如果你的模型類中包含一個主鍵,Realm可以智能的以這個主鍵來更新或添加數(shù)據(jù)箱熬。

- (void)addOrUpdateObject:(RLMObject *)object;
  • 使用KVC修改數(shù)據(jù)

如果你是一個iOS開發(fā)者类垦,你將很熟悉KVC,Realm類中例如對象狈邑、結果集、list也是兼容KVC的蚤认。這樣可以幫助你利用runtime設置/更新屬性米苹。看看這個例子:

RLMResults<Dog *> *dogs = [Dog allObjects];
[[RLMRealm defaultRealm] transactionWithBlock:^{
  [[Dog firstObject] setValue:@20 forKeyPath:@"age"];
  // set each person's name property to "wangwu"
  [dogs setValue:@"wangwu" forKeyPath:@"name"];
}];

說明:對于增加砰琢、刪除蘸嘶、修改必須要在事務中進行操作。

查詢數(shù)據(jù)

查詢會返回RLMResults結果集陪汽,它里面包含了RLMObject對象的集合训唱。RLMResults的接口方法非常類似于NSArray一樣可以使用下標索引訪問元素。與NSArray不同的是挚冤,RLMResults的元素類型只有單一的RLMObject的子類型况增。所有的查詢都是懶查詢,即只有當訪問屬性時训挡,數(shù)據(jù)才會被讀取出來澳骤。查詢的結果不是拷貝本地磁盤中的數(shù)據(jù)而是直接原始數(shù)據(jù),所以修改某一處的數(shù)據(jù)將會直接修改磁盤中的數(shù)據(jù)澜薄。在結果集被使用的過程中为肮,查詢的執(zhí)行是會被延遲的。這意味著鏈接幾個臨時中間的RLMResults所進行的排序和過濾數(shù)據(jù)的操作不執(zhí)行額外的工作去處理中間的狀態(tài)表悬。一旦查詢已經(jīng)被執(zhí)行或者通知block已經(jīng)被添加,RLMResult在可能的情況下在后臺線程上執(zhí)行查詢以保證RLMResult的結果始終是Relam中最新的丧靡。

  • 查詢?nèi)繑?shù)據(jù)
RLMResults<Dog *> *dogs = [Dog allObjects];

或者指定Realm數(shù)據(jù)庫:

NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *realmPath = [path stringByAppendingPathComponent:@"guojie.realm"];
RLMRealm *realm = [RLMRealm realmWithPath:realmPath];
RLMResults *results = [Dog allObjectsInRealm:realm];

在條件查詢中蟆沫,如果你熟悉謂詞,那么你已經(jīng)知道該如何查詢了温治。RLMObjects, RLMRealm, RLMArray, and RLMResults都提供了允許讓你通過傳遞一個謂詞實例饭庞、謂詞字符串、謂詞格式字符串來查詢具體RLMObject實例的方法熬荆。

  • 條件查詢

假設要查詢名字是guojie和年齡是10的dog對象:

RLMResults *results = [Dog objectsWhere:@"name = 'haha' AND age = 10"];

也可以使用謂詞查詢:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"type = '%@' AND name = '%@'", @"taidi", @"haha"];
RLMResults *results = [Dog objectsWithPredicate:pred]
  • 條件排序

假設已經(jīng)查詢出type是taidi舟山,name是haha的數(shù)據(jù)結果集后,需要將結果按照num字段進行遞減排序:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"type = '%@' AND name = '%@'", @"taidi", @"haha"];
RLMResults *results = [Dog objectsWithPredicate:pred];
results = [results sortedResultsUsingProperty:@"numId" ascending:NO];

請注意:結果集的順序只能保證在查詢排序時保持一致卤恳,出于性能的原因累盗,查詢順序不保證被保存。如果你需要為何查詢的順序突琳,則需要其他一些解決方案若债。

  • 鏈式查詢(結果過濾)

假設要查詢的還是type是taidi,name是haha的結果集,還可以這樣處理:

RLMResults *results1 = [Dog objectsWhere:@"type = 'taidi'"];
RLMResults *results2 = [results1 objectsWhere:@"name = 'haha'"];

通知

每當一次寫事務完成Realm實例都會向其他線程上的實例發(fā)出通知拆融,可以通過注冊一個block來響應通知:

self.token = [realm addNotificationBlock:^(NSString *note, RLMRealm * realm) {
    [_listTableView reloadData];
}];

只要有任何的引用指向這個返回的notification token蠢琳,它就會保持激活狀態(tài)啊终。在這個注冊更新的類里,你需要有一個強引用來鉗制這個token傲须, 因為一旦notification token被釋放蓝牲,通知也會自動解除注冊。

@property (nonatomic, strong) RLMNotificationToken *token;

另外可以使用下面的方式解除通知:

[realm removeNotification:self.token];

Realm版本遷移

當你和數(shù)據(jù)庫打交道的時候泰讽,你需要改變數(shù)據(jù)模型(Model)例衍,但是因為Realm中的數(shù)據(jù)模型被定義為標準的Objective-C interfaces,要改變模型,就像改變其他Objective-C interface一樣輕而易舉菇绵。舉個例子肄渗,假設有個數(shù)據(jù)模型Person:

@interface Person : RLMObject
@property NSString *firstName;
@property NSString *lastName;
@property int age;
@end

當我們想添加一個字段fullName屬性而不是first和last names時,我們可以這樣做:

@interface Person : RLMObject
@property NSString *fullName;
@property int age;
@end

接下來執(zhí)行遷移:

// Inside your [AppDelegate didFinishLaunchingWithOptions:]

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.schemaVersion = 1;
config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
  //如果從沒遷移過咬最,oldSchemaVersion == 0
  if (oldSchemaVersion < 1) {
    // The enumerateObjects:block: method iterates
    // over every 'Person' object stored in the Realm file
    [migration enumerateObjects:Person.className
                          block:^(RLMObject *oldObject, RLMObject *newObject) {

      // 設置新增屬性的值
      newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@",
                                         oldObject[@"firstName"],
                                         oldObject[@"lastName"]];
    }];
  }
};
[RLMRealmConfiguration setDefaultConfiguration:config];

在遷移的過程中重命名屬性名稱

// Inside your [AppDelegate didFinishLaunchingWithOptions:]

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.schemaVersion = 1;
config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
  // We haven’t migrated anything yet, so oldSchemaVersion == 0
  if (oldSchemaVersion < 1) {
    // The renaming operation should be done outside of calls to `enumerateObjects:`.
    [migration renamePropertyForClass:Person.className oldName:@"yearsSinceBirth" newName:@"age"];
  }
};
[RLMRealmConfiguration setDefaultConfiguration:config];

JSON

Realm并沒有直接的支持JSON,但是它可以使用[NSJSONSerialization JSONObjectWithData:options:error:]轉(zhuǎn)化之后的結果翎嫡。在結合標準的API中的createOrUpdateInRealm方法就可以解決。

// A Realm Object that represents a city
@interface City : RLMObject
@property NSString *name;
@property NSInteger cityId;
// other properties left out ...
@end
@implementation City
@end // None needed

NSData *data = [@"{\"name\": \"San Francisco\", \"cityId\": 123}" dataUsingEncoding: NSUTF8StringEncoding];
RLMRealm *realm = [RLMRealm defaultRealm];

// 插入包含JSON的NSData數(shù)據(jù)
[realm transactionWithBlock:^{
  id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
  [City createOrUpdateInRealm:realm withValue:json];
}];

說明:如果在JSON中包含有嵌套的對象或數(shù)組永乌,那么會被自動被映射到一對多關系相關的嵌套對象中惑申。

多線程訪問Realm

當需要從多線程去訪問同一個Realm時,你必須初始化一個新的Realm翅雏,去得到在App中每一個線程有一個不同的實例圈驼。只要你指定相同的Realm配置,那么所有的Realm實例將指向磁盤上的同一個文件望几。Realm是不支持在線程之間共享Relam實例的绩脆。當在一個單一事務中通過批量處理來寫入非常大的數(shù)據(jù),使用多線程是非常有用的橄抹。為了避免阻塞主線程靴迫,寫入事務可以放在使用GCD在后臺進行。Realm對象不是線程安全的楼誓,所有決定了不能線程間共享玉锌。因此你必須在你想要讀取或者寫入的每一個線程中獲取到Realm的對象實例。如下是在后臺隊列中插入100萬個對象的例子:

dispatch_async(queue, ^{
  @autoreleasepool {
    // Get realm and table instances for this thread
    RLMRealm *realm = [RLMRealm defaultRealm];

    // Break up the writing blocks into smaller portions
    // by starting a new transaction
    for (NSInteger idx1 = 0; idx1 < 1000; idx1++) {
      [realm beginWriteTransaction];

      // Add row via dictionary. Property order is ignored.
      for (NSInteger idx2 = 0; idx2 < 1000; idx2++) {
        [Person createInRealm:realm
                    withValue:@{@"name"      : randomString,
                                @"birthdate" : randomDate}];
      }

      // Commit the write transaction
      // to make this data available to other threads
      [realm commitWriteTransaction];
    }
  }
});

總結

Realm是非常適合去管理本地存儲和數(shù)據(jù)庫疟羹。Realm給了你代碼層面非常強大的可擴展性和力量主守。對于大多數(shù)App甚至是游戲,我認為你是需要使用數(shù)據(jù)庫榄融,Realm值得你去使用参淫。

參考資料

https://www.appcoda.com/realm-database-swift/
http://blog.devzeng.com/blog/simple-usage-of-realm-in-ios.html
http://blog.csdn.net/xiaoluodecai/article/details/50618445
http://www.cocoachina.com/ios/20150505/11756.html
http://ios.jobbole.com/85041/
https://www.raywenderlich.com/112544/realm-tutorial-getting-started

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市愧杯,隨后出現(xiàn)的幾起案子黄刚,更是在濱河造成了極大的恐慌,老刑警劉巖民效,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件憔维,死亡現(xiàn)場離奇詭異涛救,居然都是意外死亡,警方通過查閱死者的電腦和手機业扒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門检吆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人程储,你說我怎么就攤上這事蹭沛。” “怎么了章鲤?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵摊灭,是天一觀的道長。 經(jīng)常有香客問我败徊,道長帚呼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任皱蹦,我火速辦了婚禮煤杀,結果婚禮上,老公的妹妹穿的比我還像新娘沪哺。我一直安慰自己沈自,他們只是感情好,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布辜妓。 她就那樣靜靜地躺著枯途,像睡著了一般。 火紅的嫁衣襯著肌膚如雪籍滴。 梳的紋絲不亂的頭發(fā)上酪夷,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機與錄音异逐,去河邊找鬼捶索。 笑死插掂,一個胖子當著我的面吹牛灰瞻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辅甥,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼酝润,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了璃弄?” 一聲冷哼從身側響起要销,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎夏块,沒想到半個月后疏咐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纤掸,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年浑塞,在試婚紗的時候發(fā)現(xiàn)自己被綠了借跪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡酌壕,死狀恐怖掏愁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情卵牍,我是刑警寧澤果港,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站糊昙,受9級特大地震影響辛掠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜溅蛉,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一公浪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧船侧,春花似錦欠气、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至袁梗,卻和暖如春宜鸯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背遮怜。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工淋袖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锯梁。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓即碗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親陌凳。 傳聞我的和親對象是個殘疾皇子剥懒,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

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