iOS-底層原理 09:類 & isa 經(jīng)典面試題分析

iOS 底層原理 文章匯總

本文的面試題主要涉及isa走位 & 繼承關(guān)系 & 類結(jié)構(gòu) 相關(guān)的面試題以及針對面試題的分析

【面試題】類存在幾份?

由于類的信息內(nèi)存永遠只存在一份,所以 類對象只有一份

【百度面試題】objc_object 與 對象的關(guān)系

  • 所有的對象 都是以 objc_object為模板繼承過來的

  • 所有的對象 是 來自 NSObject(OC) 遮精,但是真正到底層的 是一個objc_object(C/C++)的結(jié)構(gòu)體類型

【總結(jié)】 objc_object對象關(guān)系繼承關(guān)系

【面試題】什么是 屬性 & 成員變量 & 實例變量 核芽?

  • 屬性(property):在OC中是通過@property開頭定義合陵,且是帶下劃線成員變量 + setter + getter方法的變量

  • 成員變量(ivar):在OC的類中{}中定義的潭兽,且沒有下劃線的變量

  • 實例變量:通過當(dāng)前對象類型,具備實例化的變量王浴,是一種特殊的成員變量脆炎,例如 NSObject、UILabel氓辣、UIButton等

【附加】成員變量 和 實例變量什么區(qū)別秒裕?

  • 實例變量(即成員變量中的對象變量 就是 實例變量):以實例對象實例化來的,是一種特殊的成員變量

  • NSString常量類型钞啸, 因為不能添加屬性几蜻,如果定義在類中的{}中,是成員變量

  • 成員變量中 除去基本數(shù)據(jù)類型体斩、NSString梭稚,其他都是 實例變量(即可以添加屬性成員變量),實例變量主要是判斷是不是對象

【面試題】元類 中為什么會有 類對象 的 類方法絮吵?

中的探索中弧烤,我們知道了實例方法 存儲在中,類方法存儲在元類

為了探索我們的面試題現(xiàn)象源武,定義了以下幾個方法扼褪,來探索方法歸屬問題

  • 在LGPerson中定義一個實例方法和一個類方法
@interface LGPerson : NSObject
- (void)sayHello;
+ (void)sayHappy;

@end

@implementation LGPerson

- (void)sayHello{
    NSLog(@"LGPerson say : Hello!!!");
}

+ (void)sayHappy{
    NSLog(@"LGPerson say : Happy!!!");
}

@end
  • main 主函數(shù),用于調(diào)用自定義的方法
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        LGPerson *person = [LGPerson alloc];
        Class pClass     = object_getClass(person);
        lgObjc_copyMethodList(pClass);

        lgInstanceMethod_classToMetaclass(pClass);
        lgClassMethod_classToMetaclass(pClass);
        NSLog(@"Hello, World!");
    }
    return 0;
}
  • lgObjc_copyMethodList 函數(shù):用于獲取類的方法列表
void lgObjc_copyMethodList(Class pClass){
    unsigned int count = 0;
    Method *methods = class_copyMethodList(pClass, &count);
    for (unsigned int i=0; i < count; i++) {
        Method const method = methods[i];
        //獲取方法名
        NSString *key = NSStringFromSelector(method_getName(method));
        
        LGLog(@"Method, name: %@", key);
    }
    free(methods);
}
  • lgInstanceMethod_classToMetaclass 函數(shù):用于獲取類的實例方法
void lgInstanceMethod_classToMetaclass(Class pClass){
    
    const char *className = class_getName(pClass);
    Class metaClass = objc_getMetaClass(className);
    
    Method method1 = class_getInstanceMethod(pClass, @selector(sayHello));
    Method method2 = class_getInstanceMethod(metaClass, @selector(sayHello));

    Method method3 = class_getInstanceMethod(pClass, @selector(sayHappy));
    Method method4 = class_getInstanceMethod(metaClass, @selector(sayHappy));
    
    LGLog(@"%s - %p-%p-%p-%p",__func__,method1,method2,method3,method4);
}
  • lgClassMethod_classToMetaclass 函數(shù):用于獲取類的類方法
void lgClassMethod_classToMetaclass(Class pClass){
    
    const char *className = class_getName(pClass);
    Class metaClass = objc_getMetaClass(className);
    
    Method method1 = class_getClassMethod(pClass, @selector(sayHello));
    Method method2 = class_getClassMethod(metaClass, @selector(sayHello));

    Method method3 = class_getClassMethod(pClass, @selector(sayHappy));
    // 元類 為什么有 sayHappy 類方法 0 1
    //
    Method method4 = class_getClassMethod(metaClass, @selector(sayHappy));
    
    LGLog(@"%s-%p-%p-%p-%p",__func__,method1,method2,method3,method4);
}
  • lgIMP_classToMetaclass 函數(shù):用于獲取方法的實現(xiàn)
void lgIMP_classToMetaclass(Class pClass){
    
    const char *className = class_getName(pClass);
    Class metaClass = objc_getMetaClass(className);

    // - (void)sayHello;
    // + (void)sayHappy;
    IMP imp1 = class_getMethodImplementation(pClass, @selector(sayHello));
    IMP imp2 = class_getMethodImplementation(metaClass, @selector(sayHello));

    IMP imp3 = class_getMethodImplementation(pClass, @selector(sayHappy));
    IMP imp4 = class_getMethodImplementation(metaClass, @selector(sayHappy));

    NSLog(@"%p-%p-%p-%p",imp1,imp2,imp3,imp4);
    NSLog(@"%s",__func__);
}

以下是幾個函數(shù)調(diào)用的打印結(jié)果


image

下面我們挨個分析不同的函數(shù)

lgObjc_copyMethodList函數(shù) 分析

在這個函數(shù)中粱栖,主要是獲取LGPerson類中的方法列表,從實例方法存儲在類中脏毯,類方法存儲在元類中可以得知闹究,LGPerson的方法列表打印結(jié)果只有sayHello方法

lgInstanceMethod_classToMetaclass函數(shù) 分析

在分析前,需要先了解class_getInstanceMethod這個方法食店,主要是用于獲取實例方法渣淤,針對該方法赏寇,蘋果有如下說明

image

其大致含義就是:如果在傳入的類或者類的父類中沒有找到指定的實例方法,則返回NULL

從上面代碼可知价认,傳入的pclass類LGPerson梆砸,通過objc_getMetaClass獲取的LGPerson的元類 是元類LGPerson拿霉,函數(shù)中4個打印結(jié)果分別是:

  • method1 地址:0x1000031b0

    • 傳入的pClassLGPerson類,需要去獲取selName = sayHello的實例方法
    • 首先在LGPerson中查找,有前面的LGPerson類可知盈魁,是有這個實例方法的,所以會返回查找到的實例方法惋鹅,所以method1的地址不為0x0
  • method2 地址:0x0

    • 傳入的pClassLGPerson元類犁河,需要去獲取selName = sayHello的實例方法
    • 其查找的順序為元類 --> 根元類 --> 根類 --> nil,直到最后也沒有找到,所以class_getInstanceMethod返回NULL惠奸,其method2的地址為0x0梅誓,表示未找到
  • method3 地址:0x0

    • 傳入的pClassLGPerson類,需要去獲取selName = sayHappy的實例方法
    • 查找順序為LGPerson類 --> 根類 --> nil,也沒有找到sayhello實例方法佛南,返回NULL梗掰,所以method3的地址為0x0,表示未找到
  • method4 地址:0x100003148

    • 傳入的pClassLGPerson元類嗅回,需要去獲取selName = sayHappy的實例方法
    • 首先在LGPerson元類中查找,發(fā)現(xiàn)有sayHappy的實例方法愧怜,主要是因為類對象的類方法存儲在元類中,類方法在元類中是實例方法妈拌,然后返回查找到的實例方法拥坛,所以method3的地址為0x100003148,表示找到了指定的實例方法

lgClassMethod_classToMetaclass函數(shù) 分析

在分析前尘分,需要先了解class_getClassMethod這個方法猜惋,主要是用于獲取類方法,針對該方法培愁,蘋果有如下說明

image

其大致含義就是:如果在傳入的類或者類的父類中沒有找到指定的類方法著摔,則返回NULL

然后再來看該方法的源碼實現(xiàn),可以得出class_getClassMethod的實現(xiàn)是獲取類的類方法定续,其本質(zhì)就是獲取元類的實例方法谍咆,最終還是會走到class_getInstanceMethod,但是在這里需要注意的一點是:在getMeta源碼中私股,如果判斷出cls是元類摹察,那么就不會再繼續(xù)往下遞歸查找,會直接返回this倡鲸,其目的是為了防止元類無限遞歸查找

//獲取類方法
Method class_getClassMethod(Class cls, SEL sel)
{
    if (!cls  ||  !sel) return nil;

    return class_getInstanceMethod(cls->getMeta(), sel);
}

??
//獲取元類
 // NOT identical to this->ISA when this is a metaclass 判斷是否是元類供嚎,是元類就直接返回,反之,繼續(xù)找isa指向
Class getMeta() {
    if (isMetaClass()) return (Class)this;
    else return this->ISA();
}

源碼流程圖如下所示


源碼流程圖

所以針對該函數(shù)的打印結(jié)果有以下分析

  • method1 地址:0x0

    • pClassLGPerson類克滴,selNamesayHello
    • 首先判斷 LGPerson類 是否是元類逼争,此時不是,返回LGPerson的元類劝赔,然后在元類中查找 sayhello實例方法誓焦。查找順序如下:元類 --> 根元類 --> 根類 --> nil,最后返回NULL
  • method2 地址:0x0

    • pClassLGPerson元類着帽,selNamesayHello
    • 首先判斷 LGPerson元類 是否是元類杂伟,此時,直接返回元類启摄,然后在元類中查找 sayhello實例方法稿壁,發(fā)現(xiàn)并沒有找到,返回NULL
  • method3 地址:0x100003148

    • pClassLGPerson類歉备,selNamesayHappy
    • 首先判斷 LGPerson類 是否是元類傅是,此時不是,返回LGPerson的元類蕾羊,然后在元類中查找 sayHappy實例方法喧笔,發(fā)現(xiàn)有這個實例方法,直接返回找到的實例方法
  • method4 地址:0x100003148

    • pClassLGPerson元類龟再,selNamesayHappy
    • 首先判斷 LGPerson元類 是否是元類书闸,此時,直接返回元類利凑,然后在元類中查找 sayHappy實例方法浆劲,發(fā)現(xiàn)有這個實例方法,直接返回找到的實例方法

從上面的分析結(jié)果中哀澈,我們就發(fā)現(xiàn)了一個問題 method4也不為NULL牌借,此時就很疑惑:元類中為什么會有 sayHappy 類方法?

主要還是因為class_getClassMethod方法在元類的判斷導(dǎo)致的割按,這是蘋果人為制造的 遞歸終止條件膨报,目的就是防止無限次遞歸

lgIMP_classToMetaclass函數(shù) 分析

class_getMethodImplementation 主要是返回方法的具體實現(xiàn),針對這個方法有如下官方說明

image

其大致含義就是:該函數(shù)在向類實例發(fā)送消息時會被調(diào)用适荣,并返回一個指向方法實現(xiàn)函數(shù)的指針现柠。這個函數(shù)會比method_getImplementation(class_getInstanceMethod(cls, name))更快。返回的函數(shù)指針可能是一個指向runtime內(nèi)部的函數(shù)弛矛,而不一定是方法的實際實現(xiàn)够吩。如果類實例無法響應(yīng)selector,則返回的函數(shù)指針將是運行時消息轉(zhuǎn)發(fā)機制的一部分

下面我們也可以通過這個方法的源碼來印證上面的這個說法汪诉,

IMP class_getMethodImplementation(Class cls, SEL sel)
{
    IMP imp;

    if (!cls  ||  !sel) return nil;

    //查找方法實現(xiàn)
    imp = lookUpImpOrNil(nil, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER);

    //如果沒有找到废恋,則進行消息轉(zhuǎn)發(fā)
    if (!imp) {
        return _objc_msgForward;
    }

    return imp;
}

接下來分析這個函數(shù)中的4個打印結(jié)果

  • imp1 函數(shù)指針地址:0x100001d00
    • pClassLGPerson類谈秫,selsayHello
    • 根據(jù)LGPerson文件扒寄,可以得出LGPerson類中可以查找到sayHello的具體實現(xiàn)鱼鼓,所以返回一個imp函數(shù)指針的地址
  • imp2 函數(shù)指針地址:0x7fff66238d80

    • pClassLGPerson元類selsayHello
    • 根據(jù)類方法存儲在元類中可知该编,sayHello是一個實例方法迄本,并不存儲在元類中,也沒有其任何實現(xiàn)课竣,所以進行了消息轉(zhuǎn)發(fā)
  • imp3 函數(shù)指針地址:0x7fff66238d80

    • pClassLGPerson類嘉赎,selsayHappy
    • 根據(jù)LGPerson文件,sayHappy是一個類方法于樟,并不存儲在類中公条,也沒有其任何實現(xiàn),所以進行了消息轉(zhuǎn)發(fā)
  • imp4 函數(shù)指針地址:0x100001d30

    • pClassLGPerson元類迂曲,selsayHappy
    • 根據(jù)類方法存儲在元類文件靶橱,可以在元類中查找到sayHappy的具體實現(xiàn),所以返回一個imp函數(shù)指針的地址

總結(jié)

  • class_getInstanceMethod:獲取實例方法路捧,如果指定的或其父類不包含帶有指定選擇器的實例方法关霸,則為NULL

  • class_getClassMethod:獲取類方法,如果指定的或其父類不包含具有指定選擇器的類方法杰扫,則為NULL队寇。

  • class_getMethodImplementation:獲取方法具體實現(xiàn),如果未查找到章姓,則進行消息轉(zhuǎn)發(fā)

【面試題】iskindOfClass & isMemberOfClass 的理解

有這么幾行關(guān)于iskindOfClass & isMemberOfClass的代碼佳遣,分析出最終結(jié)果

  • iskindOfClass & isMemberOfClass 類方法調(diào)用
//-----使用 iskindOfClass & isMemberOfClass 類方法
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];       //
BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];     //
BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];       //
BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];     //
NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);
  • iskindOfClass & isMemberOfClass 實例方法調(diào)用
//------iskindOfClass & isMemberOfClass 實例方法
BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];       //
BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];     //
BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];       //
BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];     //
NSLog(@" re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n",re5,re6,re7,re8);

其最終結(jié)果打印如下


image

源碼解析

先分析結(jié)果之前,首先需要分析下這兩個方法的源碼

  • isKindOfClass 源碼解析(實例方法 & 類方法)
//--isKindOfClass---類方法凡伊、對象方法
//+ isKindOfClass:第一次比較是 獲取類的元類 與 傳入類對比零渐,再次之后的對比是獲取上次結(jié)果的父類 與 傳入 類進行對比
+ (BOOL)isKindOfClass:(Class)cls {
    // 獲取類的元類 vs 傳入類
    // 根元類 vs 傳入類
    // 根類 vs 傳入類
    // 舉例:LGPerson vs 元類 (根元類) (NSObject)
    for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

//- isKindOfClass:第一次是獲取對象類 與 傳入類對比窗声,如果不相等相恃,后續(xù)對比是繼續(xù)獲取上次 類的父類 與傳入類進行對比
- (BOOL)isKindOfClass:(Class)cls {
/*
獲取對象的類 vs 傳入的類 
父類 vs 傳入的類
根類 vs 傳入的類
nil vs 傳入的類
*/
    for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

  • isMemberOfClass 源碼解析(實例方法 & 類方法)
//-----類方法
//+ isMemberOfClass : 獲取類的元類,與 傳入類對比
+ (BOOL)isMemberOfClass:(Class)cls {
    return self->ISA() == cls;
}
//-----實例方法
//- isMemberOfClass : 獲取對象的類笨觅,與 傳入類對比
- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}

源碼分析總結(jié)

  • isKindOfClass

    • 類方法:元類(isa) --> 根元類(父類) --> 根類(父類) --> nil(父類)傳入類的對比
    • 實例方法:對象的類 --> 父類 --> 根類 --> nil傳入類的對比
  • isMemberOfClass

    • 類方法: 類的元類傳入類 對比
    • 實例方法:對象的父類傳入類 對比

然后通過斷點調(diào)試拦耐,isMemberOfClass類方法實例方法的流程是正常的,會走到上面分析的源碼见剩,而isKindOfClass根本不會走到上面分析的源碼中(I迸础!苍苞!注意這里固翰,這是一個坑點)狼纬,而是會走到下面這個源碼中,其類方法和實例方法都是走到objc_opt_isKindOfClass方法源碼中

  • 匯編調(diào)用如下


    匯編查看
  • objc_opt_isKindOfClass方法源碼如下

// Calls [obj isKindOfClass]
BOOL
objc_opt_isKindOfClass(id obj, Class otherClass)
{
#if __OBJC2__
    if (slowpath(!obj)) return NO;
    //獲取isa骂际,
    //如果obj 是對象疗琉,則isa是類,
    //如果obj是類歉铝,則isa是元類
    Class cls = obj->getIsa(); 
    if (fastpath(!cls->hasCustomCore())) {
        // 如果obj 是對象盈简,則在類的繼承鏈進行對比,
        // 如果obj是類太示,則在元類的isa中進行對比
        for (Class tcls = cls; tcls; tcls = tcls->superclass) { 
            if (tcls == otherClass) return YES;
        }
        return NO;
    }
#endif
    return ((BOOL(*)(id, SEL, Class))objc_msgSend)(obj, @selector(isKindOfClass:), otherClass);
}

為什么會這樣呢柠贤?主要是因為在llvm中編譯時對其進行了優(yōu)化處理

所以調(diào)用objc_opt_isKindOfClass實際走的邏輯如圖所示

實際執(zhí)行邏輯

案例代碼執(zhí)行結(jié)果分析

根據(jù)源碼的分析,來分析代碼執(zhí)行的結(jié)果為什么是0或者1

使用類方法結(jié)果解析

  • re1 :1 类缤,是 NSObjectNSObject 的對比臼勉,使用 +isKindOfClass
    • NSObject(傳入類,即根類) vs NSObject的元類即根元類-- 不相等
    • NSObject(傳入類餐弱,即根類) vs 根元類的父類即根類 -- 相等宴霸,返回1
  • re2 :0 ,是 NSObjectNSObject 的對比岸裙,使用 +isMemberOfClass
    • NSObject根類(傳入類) vs NSObject的元類即根元類 -- 不相等
  • re3 :0 猖败,是 LGPersonLGPerson 的對比,使用 +isisKindOfClass
    • LGPerson(傳入) vs LGPerson的元類即元類LGPerson -- 不相等
    • LGPerson(傳入) vs 元類LGPerson的父類即根元類 -- 不相等
    • LGPerson(傳入) vs 根元類的父類即根類 -- 不相等
    • LGPerson(傳入) vs 根類的父類即 nil -- 不相等
  • re4 :0 降允,是 LGPersonLGPerson 的對比恩闻,使用 +isMemberOfClass
    • LGPerson(傳入) vs 元類 -- 不相等

使用實例方法結(jié)果解析

  • re5 :1 ,是 NSObject對象NSObject 的對比剧董,使用 -isKindOfClass
    • NSObject(傳入類幢尚,即根類) vs 對象的isa即NSObject根類 -- 相等
  • re6 :1 ,是 NSObject對象NSObject 的對比翅楼,使用 -isMemberOfClass
    • NSObject(傳入類尉剩,即根類) vs 對象的類即NSObject根類 -- 相等
  • re7 :1 ,是 LGPerson對象LGPerson 的對比毅臊,使用 -isKindOfClass
    • LGPerson(傳入類) vs 對象的isa即LGPerson -- 相等
  • re8 :1 理茎,是 LGPerson對象LGPerson 的對比,使用 -isMemberOfClass
    • LGPerson(傳入類) vs 對象的類即LGPerson -- 相等
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末管嬉,一起剝皮案震驚了整個濱河市皂林,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蚯撩,老刑警劉巖础倍,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異胎挎,居然都是意外死亡沟启,警方通過查閱死者的電腦和手機忆家,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來德迹,“玉大人芽卿,你說我怎么就攤上這事∑直妫” “怎么了蹬竖?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵沼沈,是天一觀的道長流酬。 經(jīng)常有香客問我,道長列另,這世上最難降的妖魔是什么芽腾? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮页衙,結(jié)果婚禮上摊滔,老公的妹妹穿的比我還像新娘。我一直安慰自己店乐,他們只是感情好艰躺,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著眨八,像睡著了一般腺兴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上廉侧,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天页响,我揣著相機與錄音,去河邊找鬼段誊。 笑死闰蚕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的连舍。 我是一名探鬼主播没陡,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼索赏!你這毒婦竟也來了盼玄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤参滴,失蹤者是張志新(化名)和其女友劉穎强岸,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體砾赔,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡蝌箍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年青灼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妓盲。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡杂拨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出悯衬,到底是詐尸還是另有隱情弹沽,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布筋粗,位于F島的核電站策橘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏娜亿。R本人自食惡果不足惜丽已,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望买决。 院中可真熱鬧沛婴,春花似錦、人聲如沸督赤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽躲舌。三九已至丑婿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間孽糖,已是汗流浹背枯冈。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留办悟,地道東北人尘奏。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像病蛉,于是被迫代替她去往敵國和親炫加。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

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