儲存篇 - CoreData使用大全

【一】前言

Core Data框架提供了對象-關(guān)系映射(ORM)的功能锦聊,即能夠?qū)C對象轉(zhuǎn)化成數(shù)據(jù),保存在SQLite3數(shù)據(jù)庫文件中,也能夠?qū)⒈4嬖跀?shù)據(jù)庫中的數(shù)據(jù)還原成OC對象丢烘。在此數(shù)據(jù)操作期間俱箱,不需要編寫任何SQL語句国瓮。使用此功能,要添加CoreData.framework和導(dǎo)入主頭文件 <CoreData/CoreData.h>狞谱。

【二】各種類作用的介紹

創(chuàng)建Core Data Stack

  • iOS10中利用NSPersistentContainer
  • iOS10之前涉及NSManagedObjectContext揍拆、NSPersistentStoreCoordinator、NSManagedObjectModel哲嘲、NSPersistentStore這些類

【三】手動創(chuàng)建CoreData數(shù)據(jù)

我們創(chuàng)建一個和平常一樣的工程说墨,不需要勾選Use Core Data:

一、創(chuàng)建模型文件

1与斤、進入創(chuàng)建新文件肪康,command+N或者如下圖

2、選擇文件類型撩穿, 如下圖:

3磷支、設(shè)置文件名,如下圖:

4食寡、模型文件創(chuàng)建成功雾狈,會出現(xiàn)以后


建好后你會發(fā)現(xiàn)工程中多了 XXXXXXX.xcdatamodeld,我們需要在這里添加實體(首字母大寫)和實體的屬性抵皱。

二善榛、創(chuàng)建實體

1、利用可視化的方式創(chuàng)建實體呻畸,實體的功能就類似于我們的Model類移盆,具體操作如下如:

在傳統(tǒng)的項目中我們都使用OC變成,但是CoreData默認使用的是Swift語言伤为,所以我們要設(shè)置回來OC咒循,詳情見圖片


同時需要將codegen選為Manaul/None


image.png

這里我們需要創(chuàng)建Person和Card的實體以及實體屬性:

實體間的關(guān)系:選中Person實體,在Person中添加card屬性:

image.png

選中Card實體绞愚,在Card中添加person屬性:

添加完成后叙甸,他們關(guān)系如下:

三、創(chuàng)建實體類

利用可視化創(chuàng)建了實體位衩,但是我們要想獲取對應(yīng)的數(shù)據(jù)和名稱裆蒸,就必須關(guān)聯(lián)類,因此要創(chuàng)建實體類糖驴,創(chuàng)建步驟如下:

1光戈、選中 .xcdatamodeld 文件通過 Editor 創(chuàng)建:NSManagedObject subclass類文件

2哪痰、生成了4個分類
分別為A+CoreDataClass.h, A+CoreDataClass.m, A+CoreDataProperties.h,A+CoreDataProperties.m
前2個為正式類文件(可以在需要用的地方直接引用這個類久妆,這個類內(nèi)部已經(jīng)引用了后面兩個類)晌杰, 后兩個為屬性類文件。

四筷弦、手動創(chuàng)建CoreData的使用
值得注意的是:下面的例子中我們可以直接使用創(chuàng)建的目的實體類如:Dog肋演,也可以使用NSManagedObject 這一公共實體類,可以使用KVC賦值烂琴,也可以使用 . 屬性 的方式直接賦值爹殊。
    NSManagedObject *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:_context];
    [person setValue:@"lifengfeng" forKey:@"name"];
    [person setValue:[NSNumber numberWithInt:23] forKey:@"age"];
   
   +++++++++++++++++   另一個方式  +++++++++++++++++
    Dog *dog = [NSEntityDescription insertNewObjectForEntityForName:@"Dog" inManagedObjectContext:self.myContext];
    dog.name = @"name1";
    dog.age = @"12";

    for (Dog *obj in objs) {
        NSLog(@"name=%@", obj.name);
    }

1、搭建上下文環(huán)境

//1奸绷、創(chuàng)建模型對象
    //獲取模型路徑
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"NewCodeDataModel" withExtension:@"momd"];//NewCodeDataModel.xcdatamodeld
    //根據(jù)模型文件創(chuàng)建模型對象
    NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    
    //2梗夸、創(chuàng)建持久化助理
    //利用模型對象創(chuàng)建助理對象
    NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
    
    //數(shù)據(jù)庫的名稱和路徑
    NSString *docStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *sqlPath = [docStr stringByAppendingPathComponent:@"mySqlite.sqlite"];
    NSLog(@"path = %@", sqlPath);
    NSURL *sqlUrl = [NSURL fileURLWithPath:sqlPath];
    //設(shè)置數(shù)據(jù)庫相關(guān)信息
    [store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:sqlUrl options:nil error:nil];
    
    //3、創(chuàng)建上下文
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    //關(guān)聯(lián)持久化助理
    [context setPersistentStoreCoordinator:store];
    self.myContext = context;

   其中
   持久化存儲庫的類型(addPersistentStoreWithType:參數(shù)):
  (1)NSSQLiteStoreType  SQLite數(shù)據(jù)庫
  (2)NSBinaryStoreType  二進制平面文件
  (3)NSInMemoryStoreType 內(nèi)存庫号醉,無法永久保存數(shù)據(jù)

   ConcurrencyType可選項(initWithConcurrencyType:參數(shù)):
  (1)NSConfinementConcurrencyType 這個是默認項反症,每個線程一個獨立的Context,主要是為了兼容之前的設(shè)計畔派。
  (2)NSPrivateQueueConcurrencyType 創(chuàng)建一個private queue(使用GCD)铅碍,這樣就不會阻塞主線程。
  (3)NSMainQueueConcurrencyType 創(chuàng)建一個main queue线椰,使用主線程胞谈,會阻塞。

2憨愉、增:增加數(shù)據(jù)

/**
 增加數(shù)據(jù)
 */
-(void)addData{
    
    //傳入上下文烦绳,創(chuàng)建一個Person實體對象:
    NSManagedObject *person =
    [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:_context];
    
    //設(shè)置簡單屬性:
    [person setValue:@"lifengfeng" forKey:@"name"];
    [person setValue:[NSNumber numberWithInt:23] forKey:@"age"];
    
    //傳入上下文,創(chuàng)建一個Card實體對象:
    NSManagedObject *card = [NSEntityDescription insertNewObjectForEntityForName:@"Card" inManagedObjectContext:_context];
    [card setValue:@"1234567890" forKey:@"no"];
    
    //設(shè)置Person和Card之間的關(guān)聯(lián)關(guān)系:
    [person setValue:card forKey:@"card"];
    
    //利用上下文對象配紫,將數(shù)據(jù)同步到持久化存儲庫:
    NSError *error = nil;
    BOOL success = [_context save:&error];
    if (!success) {
        [NSException raise:@"訪問數(shù)據(jù)庫錯誤径密!" format:@"%@", [error localizedDescription]];
    }else{
        NSLog(@"訪問數(shù)據(jù)庫成功!");
    }
    
    // 如果是想做更新操作:只要在更改了實體對象的屬性后調(diào)用[context save:&error]笨蚁,就能將更改的數(shù)據(jù)同步到數(shù)據(jù)庫
}

3、刪:刪除數(shù)據(jù)

/**
刪除數(shù)據(jù)
*/
-(void)deleteData{
   
   //建立請求趟庄,連接實體
   NSFetchRequest *request = [[NSFetchRequest alloc] init] ;
   NSEntityDescription *person = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:_context];
   request.entity = person;
   
   //設(shè)置條件過濾(搜索name屬性中包含”lifengfeng“的那條記錄括细,注意等號必須加,可以有空格戚啥,也可以是==)
   NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=%@", @"lifengfeng"];
   request.predicate = predicate;
   
   //遍歷所有實體奋单,將每個實體的信息存放在數(shù)組中
   NSArray *arr = [_context executeFetchRequest:request error:nil];
   
   //刪除并保存
   if(arr.count)
   {
       for (NSEntityDescription *p in arr)
       {
           [_context deleteObject:p];
           NSLog(@"刪除%@成功!",p.name);
       }
       //保存
       [_context save:nil];
   }
}

4猫十、改:修改數(shù)據(jù)

/**
 修改數(shù)據(jù)
 */
-(void)updateData{
    //建立請求览濒,連接實體
    NSFetchRequest *request = [[NSFetchRequest alloc] init] ;
    NSEntityDescription *person = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:_context];
    request.entity = person;
    
    //設(shè)置條件過濾(搜索所有name屬性不為“l(fā)ifengfeng”的數(shù)據(jù))
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name!=%@", @"lifengfeng"];
    request.predicate = predicate;
    
    //遍歷所有實體呆盖,將每個實體的信息存放在數(shù)組中
    NSArray *arr = [_context executeFetchRequest:request error:nil];
    
    //更改并保存
    if(arr.count)
    {
        for (NSEntityDescription *p in arr)
        {
            p.name = @"更改";
        }
        //保存
        [_context save:nil];
    }
    else
    {
        NSLog(@"無檢索");
    }
}

5、查:查詢數(shù)據(jù)

/**
 查詢數(shù)據(jù)
 */
-(void)queryData{
    
    //初始化一個查詢請求:
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    
    //設(shè)置要查詢的實體:
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:_context];
    request.entity = entity;
    
    //設(shè)置排序(按照age降序):
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:NO];
    request.sortDescriptors = [NSArray arrayWithObject:sort];
    
    //設(shè)置條件過濾(name like '%lifengfeng%'):
    //設(shè)置條件過濾時贷笛,數(shù)據(jù)庫里面的%要用*來代替
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*lifengfeng*"];
    request.predicate = predicate;
    //執(zhí)行請求:
    NSError *error = nil;
    NSArray *objs = [_context executeFetchRequest:request error:&error];
    if (error) {
        [NSException raise:@"查詢錯誤" format:@"%@", [error localizedDescription]];
    }
    //遍歷數(shù)據(jù):
    for (NSManagedObject *obj in objs) {
        NSLog(@"name=%@", [obj valueForKey:@"name"]);
    }
}

【四】使用系統(tǒng)自動創(chuàng)建的CoreData

系統(tǒng)幫我們在AppDelegate中創(chuàng)建了一個NSPersistentContainer實例应又,以及一個saveContext方法。(并且已經(jīng)幫我們創(chuàng)建了.xcdatamodeld模型文件)
注意看saveContext乏苦,我們通過NSPersistentContainer的屬性viewContext拿到NSManagedObjectContext對象株扛,再通過save:方法進行數(shù)據(jù)的保存。
因為系統(tǒng)并沒有幫我們適配舊系統(tǒng)汇荐,所以如果App要在非iOS10的舊系統(tǒng)運行洞就,還需要做類似上面 “搭建上下文環(huán)境”的工作,因為那里的代碼在iOS10以下和以上的代碼中都可以執(zhí)行掀淘。
如果是Xcode8之前的版本自動創(chuàng)建的Core Data Stack旬蟋,會不一樣(跟情況2類似),如下圖:

一個大坑:

這里有個坑革娄,在Xcode8中倾贰,Codegen下拉選擇框中增加了Class/Definition這一選項,而且是默認的預(yù)設(shè)值稠腊,這時候系統(tǒng)會自動幫我們這個實體創(chuàng)建了NSManagedObject子類躁染,我們不需要再創(chuàng)建實體類,最坑的是架忌,這些自動創(chuàng)建的類吞彤,在導(dǎo)航面板是看不見的!L痉拧饰恕!然后你很容易再重復(fù)手動創(chuàng)建NSManagedObject子類,這時候就會報類似「duplicate symbol _OBJC_METACLASS_Photography in:...」這類錯誤井仰。
所以埋嵌,如果你想自己手動創(chuàng)建NSManagedObject子類,就要把系統(tǒng)預(yù)設(shè)的Class/Definition改為Manual/None俱恶。

使用系統(tǒng)自動創(chuàng)建的CoreData時雹嗦,非常的方便,我們只需要在 xxxxx.xcdatamodeld 中添加好實體即可合是,然后就可以直接使用了了罪。

    #import "Man+CoreDataClass.h"
    #import "AppDelegate.h"

    AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSPersistentContainer *container = delegate.persistentContainer;
    Man *man = [NSEntityDescription insertNewObjectForEntityForName:@"Man" inManagedObjectContext:container.viewContext];
    man.name = @"小明";
    man.height = @"180";
    
    // ++++++++ 保存數(shù)據(jù) ++++++++
    NSError *error = nil;
    BOOL success = [container.viewContext save:&error];
    if (!success) {
        [NSException raise:@"訪問數(shù)據(jù)庫錯誤!" format:@"%@", [error localizedDescription]];
    }else{
        NSLog(@"訪問數(shù)據(jù)庫成功聪全!");
    }
    // ++++++++ 查詢數(shù)據(jù) ++++++++
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    //設(shè)置要查詢的實體:
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Man" inManagedObjectContext:container.viewContext];
    request.entity = entity;
    NSError *error1 = nil;
    NSArray *objs = [container.viewContext executeFetchRequest:request error:&error];
    if (error1) {
        [NSException raise:@"查詢錯誤" format:@"%@", [error1 localizedDescription]];
    }
    //遍歷數(shù)據(jù):
    for (NSManagedObject *obj in objs) {
        NSLog(@"name=%@", [obj valueForKey:@"name"]);
    }

【五】關(guān)于CoreData的版本遷移

應(yīng)用場景:修改了實體的數(shù)據(jù)結(jié)構(gòu)(比如說某個實體增加了一個特性)泊藕,因為APP版本更新后沙盒中的NSDocumentDirectory 中的緩存數(shù)據(jù)都不會被清除,這時候就要進行版本遷移了难礼,否則已經(jīng)安裝舊App的手機娃圆,在更新應(yīng)用后玫锋,兩邊數(shù)據(jù)結(jié)構(gòu)不一致導(dǎo)致不能識別,會崩潰讼呢。
步驟:

  • 選中.xcdatamodeld文件撩鹿,Editor > Add Model Version,創(chuàng)建一個新版的.xcdatamodeld文件
  • 切換到新版的.xcdatamodeld文件(切換成功后會有綠色的勾)吝岭,如下圖:
  • 對.xcdatamodeld文件進行你想要的修改
  • 創(chuàng)建NSPersistentStore的時候三痰,options參數(shù)傳一個dictionary,值如下:
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

 //在初始化的時候用到了版本遷移的設(shè)置
- (void)initializeCoreDataLessThaniOS10 {
    // Get managed object model(拿到模型文件,也就是.xcdatamodeld文件(我們會在初始化完Core data Stack后創(chuàng)建))
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MoveBand" withExtension:@"momd"];
    NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    NSAssert(mom != nil, @"Error initalizing Managed Object Model");
    
    // Create persistent store coordinator(創(chuàng)建NSPersistentStoreCoordinator對象(需要傳入上述創(chuàng)建的NSManagedObjectModel對象))
    NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
    
    // Creat managed object context(創(chuàng)建NSManagedObjectContext對象(_context是聲明在.h文件的屬性——因為其他類也要用到這個屬性))
    _context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    
    // assgin persistent store coordinator(賦值persistentStoreCoordinator)
    _context.persistentStoreCoordinator = psc;
    
    // Create .sqlite file(在沙盒中創(chuàng)建.sqlite文件)
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *documentsURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    NSURL *storeURL = [documentsURL URLByAppendingPathComponent:@"DataModel.sqlite"];
    
    // Create persistent store(異步創(chuàng)建NSPersistentStore并add到NSPersistentStoreCoordinator對象中窜管,作用是設(shè)置保存的數(shù)據(jù)類型(NSSQLiteStoreType)散劫、保存路徑、是否支持版本遷移等)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        // 用于支持版本遷移的參數(shù)
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                 [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
        NSError *error = nil;
        NSPersistentStoreCoordinator *psc = _context.persistentStoreCoordinator;
        
        // 備注幕帆,如果options參數(shù)傳nil获搏,表示不支持版本遷移
        NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType
                                                     configuration:nil
                                                               URL:storeURL
                                                           options:options
                                                             error:&error];
        NSAssert(store != nil, @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]);
    });
}

最后值得注意的是:Core Data的延遲加載

Core Data不會根據(jù)實體中的關(guān)聯(lián)關(guān)系立即獲取相應(yīng)的關(guān)聯(lián)對象,比如通過Core Data取出Person實體時失乾,并不會立即查詢相關(guān)聯(lián)的Card實體常熙;當應(yīng)用真的需要使用Card時,才會查詢數(shù)據(jù)庫碱茁,加載Card實體的信息裸卫。

【六】CoreData第三方庫:MagicalRecord

地址:MagicalRecord

CoreData是蘋果自家推出的一個持久化框架,使用起來更加面向?qū)ο笈ⅰ5窃谑褂眠^程中會出現(xiàn)大量代碼墓贿,
而且CoreData學(xué)習(xí)曲線比較陡峭,如果掌握不好蜓氨,在使用過程中很容易造成其他問題聋袋。

國外開發(fā)者開源了一個基于CoreData封裝的第三方——MagicalRecord,就像是FMDB封裝SQLite一樣穴吹,
MagicalRecord封裝的CoreData幽勒,使得原生的CoreData更加容易使用。并且MagicalRecord降低了CoreData的使用門檻港令,
不用去手動管理之前的PSC啥容、MOC等對象。

添加MagicalRecord到項目中

MagicalRecord添加到項目中顷霹,和使用其他第三方一樣咪惠,可以通過下載源碼和CocoaPods兩種方式添加。
但是不推薦直接拖源碼到項目中泼返,一是需要自己管理代碼更新硝逢,另一個原因是姨拥,直接拖源碼進項目是會報錯的绅喉,修改起來很麻煩渠鸽。

推薦通過CocoaPods安裝MagicalRecord,需要在Podfile中加入下面命令柴罐,后續(xù)只需要通過命令來更新徽缚。

pod "MagicalRecord"

很多操作在這份MagicalRecord中文文檔中都說明的很清楚,這里作簡單歸納總結(jié)

1革屠、AppDelegate中的設(shè)置

#import <MagicalRecord/MagicalRecord.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [MagicalRecord setupCoreDataStack];
    // ...
    return YES;
}
- (void)applicationWillTerminate:(UIApplication *)application
{
    [MagicalRecord cleanUp];
}

2凿试、對象的儲存和查詢

  #import <MagicalRecord/MagicalRecord.h>

    // 獲取上下文環(huán)境
    NSManagedObjectContext *localContext    = [NSManagedObjectContext MR_context];
    // 在當前上下文環(huán)境中創(chuàng)建一個新的 Person 對象.
    Man *person  = [Man MR_createEntityInContext:localContext];
    person.name = @"MagicalRecord存儲";
    // 保存修改到當前上下文中.
    [localContext MR_saveToPersistentStoreAndWait];
    
    NSArray *peopleArray = [Man MR_findAll];
    for (Man *man in peopleArray) {
        NSLog(@"名稱:%@",man.name);
    }

對于MagicalRecord 的使用感受就是,確實如它的名稱一樣似芝,如此簡潔和方便的實現(xiàn)了對象的增刪改查那婉,如此的充滿魔力,關(guān)于的它的更多使用可以參考上面的中文文檔党瓮,相信大家都可以熟練掌握這個好用的類庫详炬!

另外還有其他的第三方存儲庫: 可以存對象的數(shù)據(jù)庫realm-cocoa使用時參考這篇文章:移動端數(shù)據(jù)庫新王者:realm


參考文章:
iOS 開發(fā)之 CoreData
CoreData的使用
iOS CoreData數(shù)據(jù)庫之創(chuàng)建詳解
「死磕」Core Data——入門
認識CoreData - 初識CoreData

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市寞奸,隨后出現(xiàn)的幾起案子呛谜,更是在濱河造成了極大的恐慌,老刑警劉巖枪萄,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隐岛,死亡現(xiàn)場離奇詭異,居然都是意外死亡瓷翻,警方通過查閱死者的電腦和手機聚凹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逻悠,“玉大人元践,你說我怎么就攤上這事⊥耍” “怎么了单旁?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長饥伊。 經(jīng)常有香客問我象浑,道長,這世上最難降的妖魔是什么琅豆? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任愉豺,我火速辦了婚禮,結(jié)果婚禮上茫因,老公的妹妹穿的比我還像新娘蚪拦。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布驰贷。 她就那樣靜靜地躺著盛嘿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪括袒。 梳的紋絲不亂的頭發(fā)上次兆,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音锹锰,去河邊找鬼芥炭。 笑死,一個胖子當著我的面吹牛恃慧,可吹牛的內(nèi)容都是我干的园蝠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼痢士,長吁一口氣:“原來是場噩夢啊……” “哼砰琢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起良瞧,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤陪汽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后褥蚯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挚冤,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年赞庶,在試婚紗的時候發(fā)現(xiàn)自己被綠了训挡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡歧强,死狀恐怖澜薄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情摊册,我是刑警寧澤肤京,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站茅特,受9級特大地震影響忘分,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜白修,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一妒峦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧兵睛,春花似錦肯骇、人聲如沸窥浪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寒矿。三九已至,卻和暖如春若债,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拆融。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工蠢琳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人镜豹。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓傲须,卻偏偏與公主長得像,于是被迫代替她去往敵國和親趟脂。 傳聞我的和親對象是個殘疾皇子泰讽,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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