iOS原理 alloc核心步驟1:instanceSize詳解

iOS原理 文章匯總

前言

iOS原理 OC對象的實例化一文中介紹了alloc的底層調(diào)用流程应闯,在其核心步驟instanceSize方法里疲迂,完成了對象的內(nèi)存大小計算沸伏,返回的size即為創(chuàng)建對象需要申請的內(nèi)存空間大小须尚,本文將詳細介紹系統(tǒng)是如何計算對象內(nèi)存空間的大小。

一假消、instanceSize方法的底層實現(xiàn)

首先需要知道柠并,對象的內(nèi)存空間里存放的是對象的屬性,所以計算內(nèi)存大小即為計算所有屬性所占的內(nèi)存大小富拗,先看下objc源碼的底層實現(xiàn):

size_t instanceSize(size_t extraBytes) const {

    //方式一:編譯器快速計算內(nèi)存大芯视琛(16字節(jié)對齊)
    if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
        return cache.fastInstanceSize(extraBytes);
    }
     
    //方式二:計算類中所有屬性和方法的內(nèi)存占用 + 額外的字節(jié)數(shù)0(8字節(jié)對齊)
    size_t size = alignedInstanceSize() + extraBytes;
    //CF requires all objects be at least 16 bytes.
    //最少申請16字節(jié)的內(nèi)存大小
    if (size < 16) size = 16;
    return size;
}

上面兩個方式的區(qū)別,在于將對象所有屬性所占的內(nèi)存大小采取不同的對齊方式媒峡,方式一是16字節(jié)對齊瘟栖,方式二是8字節(jié)對齊。

注意谅阿,在不同版本的objc源碼中半哟,instanceSize方法的底層實現(xiàn)可能是不一樣的,本文參照的是最新的objc-781源碼签餐,里面會有這兩種計算方式寓涨,但是實際運行,其實是以方式一來計算的氯檐,16字節(jié)內(nèi)存對齊戒良。而在老版本的objc源碼中,比如objc-750源碼冠摄,里面只有方式二的計算方式糯崎,采取的是8字節(jié)對齊。

//objc-750源碼中的instanceSize方法
size_t instanceSize(size_t extraBytes) {

    size_t size = alignedInstanceSize() + extraBytes;
    // CF requires all objects be at least 16 bytes.
    if (size < 16) size = 16;
    return size;
}

雖然這個方法的底層實現(xiàn)不會頻繁更新河泳,但大家以后在分析時沃呢,最好是參照最新的objc源碼進行分析。話不多說拆挥,接下來分析這兩種方式具體是怎么計算的薄霜。

1.1 十六字節(jié)對齊 - fastInstanceSize

從源碼中可知,是在fastInstanceSize方法里完成內(nèi)存計算的:

size_t fastInstanceSize(size_t extra) const
{
    ASSERT(hasFastInstanceSize(extra));

    if (__builtin_constant_p(extra) && extra == 0) {
        return _flags & FAST_CACHE_ALLOC_MASK16;
    } else {
        size_t size = _flags & FAST_CACHE_ALLOC_MASK;
        // remove the FAST_CACHE_ALLOC_DELTA16 that was added
        // by setFastInstanceSize
        return align16(size + extra - FAST_CACHE_ALLOC_DELTA16);
    }
}

編譯器快速計算出需要的size后纸兔,最后會執(zhí)行align16方法片橡,即『16字節(jié)對齊』盆偿。

static inline size_t align16(size_t x) {
    return (x + size_t(15)) & ~size_t(15);
}

系統(tǒng)在計算出內(nèi)存size后伯铣,會先加15阵苇,再與個非15,這樣就實現(xiàn)了16字節(jié)對齊洲拇。接下來通過兩組二進制運算來直觀地看看字節(jié)對齊后的結(jié)果:

//已知: 15的二進制為: 0000 1111   
//      ~15的二進制為:1111 0000

//假設(shè)計算出當前類需要的內(nèi)存大小為12字節(jié)流强,則16字節(jié)對齊的計算過程如下:
0000 1100    // 12字節(jié)
0000 1111    // +15
0001 1011    // = 27
1111 0000    // ~15
0001 0000    // 27 & (~15)  = 16

//假設(shè)計算出當前類需要的內(nèi)存大小為24字節(jié)痹届,則16字節(jié)對齊的計算過程如下:
0001 1000    // 24字節(jié)
0000 1111    // +15
0010 0111    // = 39
1111 0000    // ~15
0010 0000    // 39 & (~15)  = 32

從上面兩組二進制運算得知呻待,12字節(jié)打月、24字節(jié)的內(nèi)存經(jīng)由16字節(jié)對齊后,實際申請內(nèi)存大小分別為16字節(jié)蚕捉、32字節(jié)奏篙。因此,不管對象屬性實際需要多大的內(nèi)存空間迫淹,在新版本中秘通,系統(tǒng)都會以16字節(jié)的倍數(shù)來申請內(nèi)存空間,并且最少16字節(jié)敛熬,這就是『16字節(jié)對齊』肺稀。

1.2 八字節(jié)對齊 - alignedInstanceSize
size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
if (size < 16) size = 16;
return size;

在實例化對象時,經(jīng)由斷點調(diào)試可知应民,extraBytes為0话原,所以內(nèi)存大小依賴于alignedInstanceSize方法計算:

uint32_t alignedInstanceSize() {

    //step1:通過unalignedInstanceSize方法獲取到需要的內(nèi)存大小
    //step2:通過word_align方法對內(nèi)存大小進行8字節(jié)運算
    return word_align(unalignedInstanceSize());
}

可以看到,class_getInstanceSize方法最終實現(xiàn)就兩步诲锹,先獲取到對象屬性所占的內(nèi)存大小繁仁,再將內(nèi)存大小進行8字節(jié)對齊運算。

  • unalignedInstanceSize
uint32_t unalignedInstanceSize() const {
    ASSERT(isRealized());
    return data()->ro()->instanceSize;
}

這一步獲取到的是對象的屬性所占的內(nèi)存大小归园,ro是個很重要的知識點黄虱,會在后續(xù)介紹類和對象的結(jié)構(gòu)時作詳細講解,本篇文章就不作過多拓展了庸诱。

  • word_align
#define WORD_MASK 7UL
static inline uint32_t word_align(uint32_t x) {
    return (x + WORD_MASK) & ~WORD_MASK;
}

WORD_MASK的值為7捻浦,這里其實是對內(nèi)存大小作8字節(jié)對齊運算。對齊計算和上文的16進制對齊一樣桥爽,大家可以自己進行二進制演算朱灿,這里就不再推演了。在完成8字節(jié)對齊運算后聚谁,還會再判斷size的大小母剥,如果小于16,就申請16字節(jié)的內(nèi)存形导。 也就是說环疼,不管對象的屬性實際需要多大的內(nèi)存,在老版本中朵耕,系統(tǒng)都會以8字節(jié)的倍數(shù)來申請內(nèi)存空間炫隶,并且最少16字節(jié)

二阎曹、對內(nèi)存進行字節(jié)對齊的原因

理解了內(nèi)存對齊邏輯后伪阶,可能會有疑問煞檩,為什么要對內(nèi)存進行字節(jié)對齊呢?為什么不按對象屬性實際占用的內(nèi)存大小來分配內(nèi)存呢栅贴?經(jīng)由字節(jié)對齊后斟湃,分配的空間要比實際需要的多,這樣會不會造成內(nèi)存浪費檐薯?

在解答這些疑問前凝赛,我們需要先清楚,對象里可能會有多種數(shù)據(jù)類型的屬性坛缕,這些屬性占用內(nèi)存大小是不一樣的墓猎,如果直接按照實際需要內(nèi)存進行分配,則cpu在讀取內(nèi)存數(shù)據(jù)時需要先知道每個數(shù)據(jù)占用多大內(nèi)存赚楚,這樣才能保證讀取的數(shù)據(jù)是完整的毙沾,讀取效率較低。

下面這個表格是各種類型數(shù)據(jù)分別在32位和64位系統(tǒng)中占用內(nèi)存的大小宠页,單位:字節(jié)左胞。(注:本文都是基于64位系統(tǒng)分析的)

C OC 32位 64位
bool BooL(64位) 1 1
signed char (_ _signed char)int8_t、BOOL(32位) 1 1
unsigned char Boolean 1 1
short int16_t 2 2
unsigned short unichar 2 2
int勇皇、int32_t NSInteger(32位)罩句、boolean_ t(32位) 4 4
unsigned int boolean_ t(64位)、NSUInteger(32位) 4 4
long NSInteger(64位) 4 8
unsigned long NSUlnteger(64位) 4 8
long long int64_t 8 8
float CGFloat(32位) 4 4
double CGFloat(64位) 8 8

從表格里清晰的看到敛摘,屬性最多占用8字節(jié)內(nèi)存门烂。而對象里最常見的屬性是指針類型,指針類型的數(shù)據(jù)在內(nèi)存里也是占用8字節(jié)的大小兄淫。這樣屯远,以8字節(jié)的倍數(shù)來開辟內(nèi)存空間,CPU再以8字節(jié)為一段進行讀取捕虽,既能保證每個數(shù)據(jù)讀取的完整性慨丐,又能提高讀取效率,這就是最初系統(tǒng)8字節(jié)對齊的原因泄私。

舉個例子房揭,創(chuàng)建一個Person對象,對象里有多種數(shù)據(jù)類型的屬性晌端,來看看字節(jié)對齊對分配內(nèi)存的影響捅暴。(注:這里只是看下字節(jié)對齊的影響,就先不考慮isa指針了)

@interface Person : NSObject

@property (nonatomic, strong) NSString *name;  //8
@property (nonatomic, strong) NSString *sex;   //8
@property (nonatomic, assign) int age;         //4
@property (nonatomic, assign) long height;     //8
@property (nonatomic) char c1;    //1
@property (nonatomic) char c2;    //1

@end

如果不作字節(jié)對齊咧纠,那么系統(tǒng)分配內(nèi)存會是下面的情況:

總共30字節(jié)

系統(tǒng)如果以屬性實際占用內(nèi)存大小來分配蓬痒,雖然有效利用了內(nèi)存空間,但是在讀取數(shù)據(jù)時漆羔,CPU就需要預(yù)先知道每個屬性占用的內(nèi)存大小梧奢,并按對應(yīng)字節(jié)長度讀取讀取內(nèi)存狱掂,否則讀取的數(shù)據(jù)就不完整。
比如亲轨,在上圖中趋惨,若讀取age數(shù)據(jù),如果此時CPU不按照4字節(jié)長度來讀取瓶埋,要么沒讀取到完整的age數(shù)據(jù)希柿,要么會越界讀到height的數(shù)據(jù)。
因此养筒,系統(tǒng)如果以屬性實際占用內(nèi)存大小來分配,CPU讀取內(nèi)存數(shù)據(jù)時既不安全端姚,效率也低晕粪。

所以系統(tǒng)會對內(nèi)存進行字節(jié)對齊,內(nèi)存分配情況大致如下(注:不是一定按照這個順序的):

總共32字節(jié)

若進行字節(jié)對齊渐裸,在分配內(nèi)存時巫湘,會進行屬性重排,將age昏鹃、c1尚氛、c2(總共6字節(jié))這三個屬性存在一個8字節(jié)段中,在讀取數(shù)據(jù)時洞渤,CPU也是按照8字節(jié)為一段來讀取阅嘶,這樣既能保證讀取數(shù)據(jù)的完整性,又能提高讀取效率载迄。雖說會多開辟幾字節(jié)的內(nèi)存空間讯柔,但是保證了讀取安全,提高了讀取效率护昧,完全是值得的魂迄。而且鑒于現(xiàn)在設(shè)備內(nèi)存越來越大,這種『以空間換時間』來提高效率的方式惋耙,會越來越常見捣炬。

三、計算對象申請的內(nèi)存空間大小

內(nèi)存空間里保存的是對象的屬性绽榛,所以計算內(nèi)存空間大小即是統(tǒng)計對象所有屬性所占的內(nèi)存大小湿酸。需要注意的是,對象都是繼承自NSObject的蒜田,NSObject里有個isa成員屬性稿械,是指針類型,需要占用8字節(jié)內(nèi)存冲粤。

//NSObjct的結(jié)構(gòu)
@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
    Class isa  OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}

isa的具體用途后面會講解美莫,本文不再拓展页眯。在接下來的內(nèi)存計算中,都需要加上其占用的8字節(jié)內(nèi)存厢呵。

按照前面的思路窝撵,計算對象實例化時申請的內(nèi)存空間大小,即先統(tǒng)計所有屬性所占的內(nèi)存大小襟铭,然后再進行16字節(jié)對齊就可得到碌奉。那怎么印證這個計算規(guī)則呢?最直觀的方法就是獲取并打印對象的內(nèi)存size寒砖,之前有看過其他文章赐劣,很多都是通過class_getInstanceSize方法來獲取的,先來看下這個方法的實現(xiàn)邏輯:

size_t class_getInstanceSize(Class cls){

    if (!cls) return 0;
    return cls->alignedInstanceSize();
}

可以看到哩都,class_getInstanceSize方法里面調(diào)用的是alignedInstanceSize方法魁兼,就回到了上文1.2里面的八字節(jié)對齊處理了,所以如果是老版本漠嵌,就可以正常使用咐汞,對于新版本的16字節(jié)對齊就不適用了。在新版本里可以改寫這個方法的對齊運算儒鹿,然后再使用化撕,比如這樣:

//將8字節(jié)對齊改成16字節(jié)對齊
size_t class_getInstanceSize(Class cls)
{
    if (!cls) return 0;
//    return cls->alignedInstanceSize();
    return cls->instanceSize(0);
}

但為了更直觀的區(qū)分8字節(jié)和16字節(jié)的對齊結(jié)果,這里我選擇在class_createInstanceFromZone方法里打印需要申請的內(nèi)存大小约炎。

  • 先在objc-runtime-new.h文件里添加一個老版本8字節(jié)對齊的方法植阴。
//這也是objc-750版本的instanceSize方法
size_t oldInstanceSize(size_t extraBytes) const {

    size_t size = alignedInstanceSize() + extraBytes;
    // CF requires all objects be at least 16 bytes.
    if (size < 16) size = 16;
    return size;
}
  • 然后在class_createInstanceFromZone方法里再獲取一個8字節(jié)對齊的結(jié)果,并將兩種對齊方式的內(nèi)存大小打印出來章钾。
//這是原本的16字節(jié)對齊計算
size_t size;
size = cls->instanceSize(extraBytes);
if (outAllocatedSize) *outAllocatedSize = size;

//這里再獲取一個8字節(jié)對齊結(jié)果
size_t size8;
size8 = cls->oldInstanceSize(extraBytes);

//打印兩個結(jié)果
printf("size16 = %lu \nsize8 = %lu\n", size, size8);
  • 最后實例化Person對象墙贱,打印結(jié)果。為了對比更加直觀贱傀,也打印出通過class_getInstanceSize方法獲取到的內(nèi)存大小惨撇。

準備工作完成,那接下來分析在各種情況下創(chuàng)建Person對象需要申請的內(nèi)存空間大小府寒。

3.1 不含任何自定義屬性的Person對象
//不含自定義屬性的Person對象
@interface Person : NSObject
@end

//創(chuàng)建Person對象魁衙,打印內(nèi)存大小
Person *person = [[Person alloc] init];
NSLog(@"class_getInstanceSize = %lu", class_getInstanceSize([Person class]));

//打印結(jié)果
size16 = 16                 //16字節(jié)對齊的結(jié)果
size8 = 16                  //8字節(jié)對齊的結(jié)果
class_getInstanceSize = 8   //獲取的8字節(jié)對齊的內(nèi)存

person對象里只有一個isa屬性,占8字節(jié)株搔,那屬性總共占用8字節(jié)的內(nèi)存大衅实怼:

  • size16 = 16:經(jīng)由16字節(jié)對齊后,結(jié)果為16字節(jié)纤房。
  • size8 = 16:經(jīng)由8字節(jié)對齊后纵隔,結(jié)果為8字節(jié)。但oldInstanceSize方法最后對內(nèi)存大小進行了判斷,如果小于16捌刮,就返回16碰煌。
  • class_getInstanceSize = 8:這個方法只作了8字節(jié)對齊,所以返回為8绅作。
3.2 自定義指針類型屬性的Person對象
//聲明兩個指針類型的屬性
@interface Person : NSObject

@property (nonatomic, strong) NSString *name;  //8
@property (nonatomic, strong) NSString *sex;   //8

@end

//創(chuàng)建Person對象芦圾,打印內(nèi)存大小
Person *person = [[Person alloc] init];
NSLog(@"class_getInstanceSize = %lu", class_getInstanceSize([Person class]));

//打印結(jié)果
size16 = 32                  //16字節(jié)對齊的結(jié)果
size8 = 24                   //8字節(jié)對齊的結(jié)果
class_getInstanceSize = 24   //獲取的8字節(jié)對齊的內(nèi)存

person對象里有三個指針類型的數(shù)據(jù)(isa,name俄认,sex)个少,屬性總共占用24字節(jié)的內(nèi)存大小:

  • size16 = 32:經(jīng)由16字節(jié)對齊后眯杏,結(jié)果為32字節(jié)夜焦。
  • size8 = 24:經(jīng)由8字節(jié)對齊后,結(jié)果為24字節(jié)役拴。
  • class_getInstanceSize = 24:這個方法只作了8字節(jié)對齊糊探,所以返回為24。
3.3 自定義多種數(shù)據(jù)類型屬性的Person對象
//Person類里自定義了多種類型的屬性
@interface Person : NSObject

@property (nonatomic, strong) NSString *name;  //8
@property (nonatomic, strong) NSString *sex;   //8
@property (nonatomic, assign) int age;         //4
@property (nonatomic, assign) long height;     //8
@property (nonatomic) char c1;                 //1
@property (nonatomic) char c2;                 //1

@end
  
//創(chuàng)建Person對象河闰,打印內(nèi)存大小
Person *person = [[Person alloc] init];
NSLog(@"class_getInstanceSize = %lu", class_getInstanceSize([Person class]));

//打印結(jié)果
size16 = 48                  //16字節(jié)對齊的結(jié)果
size8 = 40                   //8字節(jié)對齊的結(jié)果
class_getInstanceSize = 40   //獲取的8字節(jié)對齊的內(nèi)存

person對象里的屬性總共占用38字節(jié)的內(nèi)存大小:

  • size16 = 48:經(jīng)由16字節(jié)對齊后褥紫,結(jié)果為48字節(jié)姜性。
  • size8 = 40:經(jīng)由8字節(jié)對齊后,結(jié)果為40字節(jié)髓考。
  • class_getInstanceSize = 40:這個方法只作了8字節(jié)對齊部念,所以返回為40。
3.4 對象里包含結(jié)構(gòu)體成員屬性

在Person對象里添加結(jié)構(gòu)體成員氨菇,再看下打印結(jié)果儡炼。

//聲明一個結(jié)構(gòu)體struct1,根據(jù)前面的分析可知查蓉,內(nèi)存為24乌询。
struct Struct1 {
    double a;   // 8 
    char b;     // 1
    int c;      // 4
    short d;    // 2
};

//在person最后面添加一個struct1的類
@interface Person : NSObject

@property (nonatomic, strong) NSString *name;  //8
@property (nonatomic, assign) int age;         //4
@property (nonatomic, assign) long height;     //8
@property (nonatomic) char c1;    //1
@property (nonatomic) struct Struct1 str;    //24

@end

//創(chuàng)建Person對象,打印內(nèi)存大小
Person *person = [[Person alloc] init];
NSLog(@"class_getInstanceSize = %lu", class_getInstanceSize([Person class]));

//打印結(jié)果
size16 = 64                  //16字節(jié)對齊的結(jié)果
size8 = 56                   //8字節(jié)對齊的結(jié)果
class_getInstanceSize = 56   //獲取的8字節(jié)對齊的內(nèi)存

person對象其他屬性占用了29個字節(jié)豌研,在對象內(nèi)存里存放在位置0-28 妹田。結(jié)構(gòu)體str成員,本應(yīng)該在位置29處開始存放鹃共,但根據(jù)結(jié)構(gòu)體內(nèi)存對齊規(guī)則鬼佣,當結(jié)構(gòu)體作為成員時,則結(jié)構(gòu)體成員要從其內(nèi)部最?元素所占內(nèi)存??的整數(shù)倍地址開始存儲霜浴,結(jié)構(gòu)體str里最大成員占用8字節(jié)內(nèi)存晶衷,所以str需要從8的整數(shù)倍開始存儲,即從位置32開始存放,存放位置為32-55晌纫,所以最后person對象需要56字節(jié)內(nèi)存:

  • size16 = 64:經(jīng)由16字節(jié)對齊后税迷,結(jié)果為64字節(jié)。
  • size8 = 56:經(jīng)由8字節(jié)對齊后缸匪,結(jié)果為56字節(jié)翁狐。
  • class_getInstanceSize = 56:這個方法只作了8字節(jié)對齊,所以返回為56凌蔬。

通過分析上述示例的打印結(jié)果露懒,均可印證前面說的內(nèi)存大小的計算規(guī)則:先統(tǒng)計所有屬性所占的內(nèi)存大小,然后再進行16字節(jié)對齊砂心。簡單數(shù)據(jù)類型的屬性所占內(nèi)存比較容易統(tǒng)計懈词,但對于比較復(fù)雜的數(shù)據(jù)結(jié)構(gòu),比如說結(jié)構(gòu)體(struct)辩诞,它的內(nèi)存計算就需要遵循『結(jié)構(gòu)體內(nèi)存對齊規(guī)則』坎弯。

四、sizeof & class_getInstanceSize & malloc_size

在打印內(nèi)存大小時译暂,用到了這三個方法:

  • sizeof:是一個運算符抠忘,用來計算傳進來的數(shù)據(jù)類型占用多大的內(nèi)存,在編譯時即可完成運算外永。
  • class_getInstanceSize:獲取對象實例化時需要申請的內(nèi)存大小崎脉,采取的是8字節(jié)對齊方式,調(diào)用時需要先引用#import <objc/runtime.h>伯顶。
  • malloc_size:獲取對象實例化時系統(tǒng)實際開辟的內(nèi)存大小囚灼,采取的是16字節(jié)對齊方式,調(diào)用時需要先引用#import <malloc/malloc.h>祭衩。

五灶体、總結(jié)

  • 對象的內(nèi)存大小依賴其包含的屬性,所以在實例化對象時掐暮,系統(tǒng)會先統(tǒng)計對象所有屬性所占的內(nèi)存大小蝎抽,再經(jīng)由16字節(jié)對齊(老版本是8字節(jié)對齊),計算出需要申請的內(nèi)存空間大小劫乱,所以對象的內(nèi)存大小只會是16的整數(shù)倍织中,并且最少申請16字節(jié)大小的內(nèi)存。

  • 對內(nèi)存大小作16字節(jié)對齊或8字節(jié)對齊衷戈,主要是為了保證cpu讀取內(nèi)存數(shù)據(jù)的安全狭吼,以及提高讀取效率。

  • 若數(shù)據(jù)類型為結(jié)構(gòu)體(struct)殖妇,在計算內(nèi)存大小時需要遵循結(jié)構(gòu)體內(nèi)存對齊原則刁笙,詳細介紹可參考下方推薦閱讀里的『數(shù)據(jù)結(jié)構(gòu) -- 結(jié)構(gòu)體Struct』一文。

推薦閱讀

1. iOS原理 OC對象的實例化
2. iOS原理 alloc核心步驟2:calloc詳解
3. iOS原理 alloc核心步驟3:initInstanceIsa詳解
4. 數(shù)據(jù)結(jié)構(gòu) -- 結(jié)構(gòu)體Struct

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市疲吸,隨后出現(xiàn)的幾起案子座每,更是在濱河造成了極大的恐慌,老刑警劉巖摘悴,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峭梳,死亡現(xiàn)場離奇詭異,居然都是意外死亡蹂喻,警方通過查閱死者的電腦和手機葱椭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來口四,“玉大人孵运,你說我怎么就攤上這事÷剩” “怎么了治笨?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赤嚼。 經(jīng)常有香客問我旷赖,道長,這世上最難降的妖魔是什么更卒? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任杠愧,我火速辦了婚禮,結(jié)果婚禮上逞壁,老公的妹妹穿的比我還像新娘。我一直安慰自己锐锣,他們只是感情好腌闯,可當我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雕憔,像睡著了一般姿骏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上斤彼,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天分瘦,我揣著相機與錄音,去河邊找鬼琉苇。 笑死嘲玫,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的并扇。 我是一名探鬼主播去团,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了土陪?” 一聲冷哼從身側(cè)響起昼汗,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鬼雀,沒想到半個月后顷窒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡源哩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年鞋吉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片璧疗。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡坯辩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出崩侠,到底是詐尸還是另有隱情漆魔,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布却音,位于F島的核電站改抡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏系瓢。R本人自食惡果不足惜阿纤,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望夷陋。 院中可真熱鬧欠拾,春花似錦、人聲如沸骗绕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酬土。三九已至荆忍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間撤缴,已是汗流浹背刹枉。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留屈呕,地道東北人微宝。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像凉袱,于是被迫代替她去往敵國和親芥吟。 傳聞我的和親對象是個殘疾皇子侦铜,可洞房花燭夜當晚...
    茶點故事閱讀 44,969評論 2 355