走進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ā)者能夠用僅僅幾行代碼完成你所需要的一切功能。它旨在打造讓用戶得在到移動領(lǐng)域離線時的最好體驗峦剔,我整理了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)上的相關(guān)教程鸳君。

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

Pod init

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

接下來執(zhí)行Pod install命令去下載Realm安裝到項目中。完成之后沼溜,你將看到新的Xcode項目的workspace在Podfile文件被生成平挑。請打開Xcode的RealmDemo.xworkspace和不要打開xcodeproj。打開workspace之后系草,你將看到Pod相關(guān)文件已經(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)建出來的纫版,它包含了關(guān)于數(shù)據(jù)庫表中實體床绪、屬性和記錄的信息。目前直接在Mac App Store中搜索Realm Browser進行下載即可。下載完成后癞己,打開Realm瀏覽器選擇Tools-> Generate demo database膀斋。它將為你生成測試數(shù)據(jù)庫文件和你可以打開它看到里面的數(shù)據(jù)。當你打開你的demo database時你應該看到

正如你看到的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ù)庫(名稱愉耙、路徑)
//注意:新版本中關(guān)于配置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è)置是否只讀數(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中設(shè)置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的構(gòu)建數(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對象來表示一條小狗店量,緊接向類中添加屬性芜果。然后類在添加屬性之后向如下這樣:

  • 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

/**
 設(shè)置主鍵
 */
+ (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(guān)系(Realm也支持RLMObject繼承)

  3. Realm忽略了Objective-C的property attributes(如nonatomic, atomic, strong, copy, weak 等等)融师。 所以右钾,推薦在創(chuàng)建模型的時候不要使用任何的property attributes。但是,假如你設(shè)置了舀射,這些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: 可以被重寫來設(shè)置模型的主鍵山林。定義主鍵可以提高效率并且確保唯一性。
    • + (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對象,依次設(shè)置各個屬性

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

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

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

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

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)建一個對象左驾。注意被設(shè)置為必須的屬性在被添加之前一定要被設(shè)置值。
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í)行許多讀取操作時在后臺同一時間寫入事務(wù)可能也會在后臺執(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類中例如對象音羞、結(jié)果集柿究、list也是兼容KVC的。這樣可以幫助你利用runtime設(shè)置/更新屬性黄选∮看看這個例子:

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"];
}];

說明:對于增加婶肩、刪除、修改必須要在事務(wù)中進行操作貌夕。

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

查詢會返回RLMResults結(jié)果集律歼,它里面包含了RLMObject對象的集合。RLMResults的接口方法非常類似于NSArray一樣可以使用下標索引訪問元素啡专。與NSArray不同的是险毁,RLMResults的元素類型只有單一的RLMObject的子類型。所有的查詢都是懶查詢们童,即只有當訪問屬性時畔况,數(shù)據(jù)才會被讀取出來。查詢的結(jié)果不是拷貝本地磁盤中的數(shù)據(jù)而是直接原始數(shù)據(jù)慧库,所以修改某一處的數(shù)據(jù)將會直接修改磁盤中的數(shù)據(jù)跷跪。在結(jié)果集被使用的過程中,查詢的執(zhí)行是會被延遲的齐板。這意味著鏈接幾個臨時中間的RLMResults所進行的排序和過濾數(shù)據(jù)的操作不執(zhí)行額外的工作去處理中間的狀態(tài)吵瞻。一旦查詢已經(jīng)被執(zhí)行或者通知block已經(jīng)被添加,RLMResult在可能的情況下在后臺線程上執(zhí)行查詢以保證RLMResult的結(jié)果始終是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實例的方法滋觉。

  • 條件查詢

假設(shè)要查詢名字是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]
  • 條件排序

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

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

請注意:結(jié)果集的順序只能保證在查詢排序時保持一致椎瘟,出于性能的原因,查詢順序不保證被保存侄旬。如果你需要為何查詢的順序肺蔚,則需要其他一些解決方案。

  • 鏈式查詢(結(jié)果過濾)

假設(shè)要查詢的還是type是taidi,name是haha的結(jié)果集儡羔,還可以這樣處理:

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

通知

每當一次寫事務(wù)完成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è)有個數(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) {

      // 設(shè)置新增屬性的值
      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)化之后的結(jié)果。在結(jié)合標準的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ù)組噪裕,那么會被自動被映射到一對多關(guān)系相關(guān)的嵌套對象中。

多線程訪問Realm

當需要從多線程去訪問同一個Realm時股毫,你必須初始化一個新的Realm膳音,去得到在App中每一個線程有一個不同的實例。只要你指定相同的Realm配置皇拣,那么所有的Realm實例將指向磁盤上的同一個文件严蓖。Realm是不支持在線程之間共享Relam實例的。當在一個單一事務(wù)中通過批量處理來寫入非常大的數(shù)據(jù)氧急,使用多線程是非常有用的颗胡。為了避免阻塞主線程,寫入事務(wù)可以放在使用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];
    }
  }
});

總結(jié)

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

參考資料

  1. Building a ToDo App Using Realm and Swift
  2. iOS中Realm數(shù)據(jù)庫的基本用法
  3. Realm-在iOS中應用-全新的數(shù)據(jù)庫思維模式
  4. Realm數(shù)據(jù)庫基礎(chǔ)教程
  5. 移動端數(shù)據(jù)庫新王者:realm
  6. Realm Tutorial: Getting Started
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逮走,一起剝皮案震驚了整個濱河市鸠蚪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌师溅,老刑警劉巖茅信,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異墓臭,居然都是意外死亡蘸鲸,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門窿锉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來酌摇,“玉大人膝舅,你說我怎么就攤上這事∶畋裕” “怎么了铸史?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長怯伊。 經(jīng)常有香客問我琳轿,道長,這世上最難降的妖魔是什么耿芹? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任崭篡,我火速辦了婚禮,結(jié)果婚禮上吧秕,老公的妹妹穿的比我還像新娘琉闪。我一直安慰自己,他們只是感情好砸彬,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布颠毙。 她就那樣靜靜地躺著,像睡著了一般砂碉。 火紅的嫁衣襯著肌膚如雪蛀蜜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天增蹭,我揣著相機與錄音滴某,去河邊找鬼。 笑死滋迈,一個胖子當著我的面吹牛霎奢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播饼灿,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼幕侠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了碍彭?” 一聲冷哼從身側(cè)響起晤硕,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎硕旗,沒想到半個月后窗骑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體女责,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡漆枚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了抵知。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片墙基。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡软族,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出残制,到底是詐尸還是另有隱情立砸,我是刑警寧澤塑猖,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布呀页,位于F島的核電站,受9級特大地震影響泌枪,放射性物質(zhì)發(fā)生泄漏恼布。R本人自食惡果不足惜螺戳,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望折汞。 院中可真熱鬧倔幼,春花似錦、人聲如沸爽待。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸟款。三九已至膏燃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間欠雌,已是汗流浹背蹄梢。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留富俄,地道東北人禁炒。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像霍比,于是被迫代替她去往敵國和親幕袱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

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