IOS基礎(chǔ)面試二

轉(zhuǎn)載自:iOS 面試題

28、找出兩個(gè) UIView 的最近的公共 View裹刮,如果不存在音榜,則輸出 nil 。

分析:這其實(shí)是數(shù)據(jù)結(jié)構(gòu)里面的找最近公共祖先的問(wèn)題捧弃。

一個(gè) UIViewController 中的所有 view 之間的關(guān)系其實(shí)可以看成一顆樹(shù)赠叼,UIViewController 的 view 變量是這顆樹(shù)的根節(jié)點(diǎn),其它的 view 都是根節(jié)點(diǎn)的直接或間接子節(jié)點(diǎn)违霞。

所以我們可以通過(guò) view 的 superview 屬性嘴办,一直找到根節(jié)點(diǎn)。需要注意的是葛家,在代碼中户辞,我們還需要考慮各種非法輸入,如果輸入了 nil癞谒,則也需要處理,避免異常刃榨。以下是找到指定 view 到根 view 的路徑代碼:

+ (NSArray *)superViews:(UIView *)view {
    if (view == nil) {
        return @[];
    }
    NSMutableArray *result = [NSMutableArray array];
    while (view != nil) {
        [result addObject:view];
        view = view.superview;
    }
    return [result copy];
}

然后對(duì)于兩個(gè) view A 和 view B弹砚,我們可以得到兩個(gè)路徑,而本題中我們要找的是這里面最近的一個(gè)公共節(jié)點(diǎn)枢希。

一個(gè)簡(jiǎn)單直接的辦法:拿第一個(gè)路徑中的所有節(jié)點(diǎn)桌吃,去第二個(gè)節(jié)點(diǎn)中查找。假設(shè)路徑的平均長(zhǎng)度是 N苞轿,因?yàn)槊總€(gè)節(jié)點(diǎn)都要找 N 次茅诱,一共有 N 個(gè)節(jié)點(diǎn)逗物,所以這個(gè)辦法的時(shí)間復(fù)雜度是 O(N^2)。

+ (UIView *)commonView_1:(UIView *)viewA andView:(UIView *)viewB {
    NSArray *arr1 = [self superViews:viewA];
    NSArray *arr2 = [self superViews:viewB];
    for (NSUInteger i = 0; i < arr1.count; ++i) {
        UIView *targetView = arr1[i];
        for (NSUInteger j = 0; j < arr2.count; ++j) {
            if (targetView == arr2[j]) {
                return targetView;
            }
        }
    }
    return nil;
}

一個(gè)改進(jìn)的辦法:我們將一個(gè)路徑中的所有點(diǎn)先放進(jìn) NSSet 中瑟俭。因?yàn)?NSSet 的內(nèi)部實(shí)現(xiàn)是一個(gè) hash 表翎卓,所以查找元素的時(shí)間復(fù)雜度變成了 O(1),我們一共有 N 個(gè)節(jié)點(diǎn)摆寄,所以總時(shí)間復(fù)雜度優(yōu)化到了 O(N)失暴。

+ (UIView *)commonView_2:(UIView *)viewA andView:(UIView *)viewB {
    NSArray *arr1 = [self superViews:viewA];
    NSArray *arr2 = [self superViews:viewB];
    NSSet *set = [NSSet setWithArray:arr2];
    for (NSUInteger i = 0; i < arr1.count; ++i) {
        UIView *targetView = arr1[i];
        if ([set containsObject:targetView]) {
            return targetView;
        }
    }
    return nil;
}

除了使用 NSSet 外,我們還可以使用類似歸并排序的思想微饥,用兩個(gè)「指針」逗扒,分別指向兩個(gè)路徑的根節(jié)點(diǎn),然后從根節(jié)點(diǎn)開(kāi)始欠橘,找第一個(gè)不同的節(jié)點(diǎn)矩肩,第一個(gè)不同節(jié)點(diǎn)的上一個(gè)公共節(jié)點(diǎn),就是我們的答案肃续。代碼如下:

/* O(N) Solution */
+ (UIView *)commonView_3:(UIView *)viewA andView:(UIView *)viewB {
    NSArray *arr1 = [self superViews:viewA];
    NSArray *arr2 = [self superViews:viewB];
    NSInteger p1 = arr1.count - 1;
    NSInteger p2 = arr2.count - 1;
    UIView *answer = nil;
    while (p1 >= 0 && p2 >= 0) {
        if (arr1[p1] == arr2[p2]) {
            answer = arr1[p1];
        }
        p1--;
        p2--;
    }
    return answer;
}

我們還可以使用 UIView 的 isDescendant 方法來(lái)簡(jiǎn)化我們的代碼黍檩,不過(guò)這樣寫(xiě)的話,時(shí)間復(fù)雜度應(yīng)該也是 O(N^2) 的痹升。lexrus 提供了如下的 Swift 版本的代碼:

/// without flatMap
extension UIView {    
func commonSuperview(of view: UIView) -> UIView? {        
    if let s = superview {            
       if view.isDescendant(of: s) {                
                 return s
            } else {                
                 return s.commonSuperview(of: view)
            }
        }        
       return nil
    }
}

特別地建炫,如果我們利用 Optinal 的 flatMap 方法,可以將上面的代碼簡(jiǎn)化得更短疼蛾,基本上算是一行代碼搞定肛跌。

extension UIView {
    func commonSuperview(of view: UIView) -> UIView? {
        return superview.flatMap { 
           view.isDescendant(of: $0) ? 
             $0 : $0.commonSuperview(of: view) 
        }
    }
}

29、什么時(shí)候在 block 中不需要使用 weakSelf

問(wèn)題

我們知道察郁,在使用 block 的時(shí)候衍慎,為了避免產(chǎn)生循環(huán)引用,通常需要使用weakSelfstrongSelf皮钠,寫(xiě)下面這樣的代碼:

__weak typeof(self) weakSelf = self;
[self doSomeBlockJob:^{
    __strong typeof(weakSelf) strongSelf = weakSelf;
    if (strongSelf) {
        ...
    }
}];

那么請(qǐng)問(wèn):什么時(shí)候在 block 里面用 self稳捆,不需要使用 weak self?

答案

當(dāng) block 本身不被 self 持有麦轰,而被別的對(duì)象持有乔夯,同時(shí)不產(chǎn)生循環(huán)引用的時(shí)候,就不需要使用 weak self 了款侵。最常見(jiàn)的代碼就是 UIView 的動(dòng)畫(huà)代碼末荐,我們?cè)谑褂?UIView 的 animateWithDuration:animations 方法 做動(dòng)畫(huà)的時(shí)候,并不需要使用 weak self新锈,因?yàn)橐贸钟嘘P(guān)系是:

UIView 的某個(gè)負(fù)責(zé)動(dòng)畫(huà)的對(duì)象持有了 block
block 持有了 self
因?yàn)?self 并不持有 block甲脏,所以就沒(méi)有循環(huán)引用產(chǎn)生,因?yàn)榫筒恍枰褂?weak self 了。

[UIView animateWithDuration:0.2 animations:^{
    self.alpha = 1;
}];

當(dāng)動(dòng)畫(huà)結(jié)束時(shí)块请,UIView 會(huì)結(jié)束持有這個(gè) block娜氏,如果沒(méi)有別的對(duì)象持有 block 的話,block 對(duì)象就會(huì)釋放掉墩新,從而 block 會(huì)釋放掉對(duì)于 self 的持有贸弥。整個(gè)內(nèi)存引用關(guān)系被解除。

30抖棘、為什么 weakSelf 需要配合 strong self 使用

在使用 block 的時(shí)候茂腥,為了避免產(chǎn)生循環(huán)引用,通常需要使用 weakSelf 與 strongSelf切省,寫(xiě)下面這樣的代碼:

__weak typeof(self) weakSelf = self;
[self doSomeBackgroundJob:^{
    __strong typeof(weakSelf) strongSelf = weakSelf;
    if (strongSelf) {
        ...
    }
}];
為什么 block 里面還需要寫(xiě)一個(gè) strong self最岗,如果不寫(xiě)會(huì)怎么樣?

在 block 中先寫(xiě)一個(gè) strong self朝捆,其實(shí)是為了避免在 block 的執(zhí)行過(guò)程中般渡,突然出現(xiàn) self 被釋放的尷尬情況。通常情況下芙盘,如果不這么做的話驯用,還是很容易出現(xiàn)一些奇怪的邏輯,甚至閃退儒老。

我們以 AFNetworkingAFNetworkReachabilityManager.m的一段代碼舉例:

__weak __typeof(self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
    __strong __typeof(weakSelf)strongSelf = weakSelf;

    strongSelf.networkReachabilityStatus = status;
    if (strongSelf.networkReachabilityStatusBlock) {
        strongSelf.networkReachabilityStatusBlock(status);
    }

};

如果沒(méi)有 strongSelf 的那行代碼蝴乔,那么后面的每一行代碼執(zhí)行時(shí),self 都可能被釋放掉了驮樊,這樣很可能造成邏輯異常薇正。

特別是當(dāng)我們正在執(zhí)行 strongSelf.networkReachabilityStatusBlock(status); 這個(gè) block 閉包時(shí),如果這個(gè) block 執(zhí)行到一半時(shí) self 釋放囚衔,那么多半情況下會(huì) Crash挖腰。

這里有一篇文章詳細(xì)解釋了這個(gè)問(wèn)題:https://dhoerl.wordpress.com/2013/04/23/i-finally-figured-out-weakself-and-strongself/

提問(wèn):
1、“數(shù)組” 和 “字典” 的 enumeratXXXUsingBlock: 是否要使用 weakSelf 和 strongSelf 呢练湿?
2猴仑、block 里 strong self 后,block 不是也會(huì)持有 self 嗎肥哎?而 self 又持有 block 辽俗,那不是又循環(huán)引用了?
在block里用strong引用篡诽,保證了持有引用的周期只在 block被執(zhí)行時(shí)榆苞,閉包函數(shù)返回后就釋放了。而直接用強(qiáng)引用霞捡,持有引用的周期則是block的生命周期,就會(huì)循環(huán)引用了薄疚。

31碧信、block 什么時(shí)候需要構(gòu)造循環(huán)引用

有沒(méi)有這樣一個(gè)需求場(chǎng)景赊琳,block 會(huì)產(chǎn)生循環(huán)引用,但是業(yè)務(wù)又需要你不能使用 weak self? 如果有砰碴,請(qǐng)舉一個(gè)例子并且解釋這種情況下如何解決循環(huán)引用問(wèn)題
答案

需要不使用 weak self 的場(chǎng)景是:你需要構(gòu)造一個(gè)循環(huán)引用躏筏,以便保證引用雙方都存在。比如你有一個(gè)后臺(tái)的任務(wù)呈枉,希望任務(wù)執(zhí)行完后趁尼,通知另外一個(gè)實(shí)例。在我們開(kāi)源的 YTKNetwork 網(wǎng)絡(luò)庫(kù)的源碼中猖辫,就有這樣的場(chǎng)景酥泞。

在 YTKNetwork 庫(kù)中,我們的每一個(gè)網(wǎng)絡(luò)請(qǐng)求 API 會(huì)持有回調(diào)的 block啃憎,回調(diào)的 block 會(huì)持有 self芝囤,而如果 self 也持有網(wǎng)絡(luò)請(qǐng)求 API 的話,我們就構(gòu)造了一個(gè)循環(huán)引用辛萍。雖然我們構(gòu)造出了循環(huán)引用悯姊,但是因?yàn)樵诰W(wǎng)絡(luò)請(qǐng)求結(jié)束時(shí)吵血,網(wǎng)絡(luò)請(qǐng)求 API 會(huì)主動(dòng)釋放對(duì) block 的持有琅锻,因此江滨,整個(gè)循環(huán)鏈條被解開(kāi)寿烟,循環(huán)引用就被打破了弃锐,所以不會(huì)有內(nèi)存泄漏問(wèn)題魂仍。代碼其實(shí)很簡(jiǎn)單三热,如下所示:

//  YTKBaseRequest.m
- (void)clearCompletionBlock {
    // nil out to break the retain cycle.
    self.successCompletionBlock = nil;
    self.failureCompletionBlock = nil;
}

總結(jié)來(lái)說(shuō)念祭,解決循環(huán)引用問(wèn)題主要有兩個(gè)辦法:

  • 第一個(gè)辦法是「事前避免」睛藻,我們?cè)跁?huì)產(chǎn)生循環(huán)引用的地方使用 weak 弱引用启上,以避免產(chǎn)生循環(huán)引用。
  • 第二個(gè)辦法是「事后補(bǔ)救」店印,我們明確知道會(huì)存在循環(huán)引用冈在,但是我們?cè)诤侠淼奈恢弥鲃?dòng)斷開(kāi)環(huán)中的一個(gè)引用,使得對(duì)象得以回收按摘。

32包券、weak 的內(nèi)部實(shí)現(xiàn)原理

問(wèn)題

weak 變量在引用計(jì)數(shù)為0時(shí),會(huì)被自動(dòng)設(shè)置成 nil炫贤,這個(gè)特性是如何實(shí)現(xiàn)的溅固?

答案

在 Friday QA 上,有一期專門(mén)介紹 weak 的實(shí)現(xiàn)原理兰珍。https://mikeash.com/pyblog/friday-qa-2010-07-16-zeroing-weak-references-in-objective-c.html

《Objective-C高級(jí)編程》一書(shū)中也介紹了相關(guān)的內(nèi)容侍郭。

簡(jiǎn)單來(lái)說(shuō),系統(tǒng)有一個(gè)全局的 CFMutableDictionary 實(shí)例,來(lái)保存每個(gè)對(duì)象的 weak 指針列表亮元,因?yàn)槊總€(gè)對(duì)象可能有多個(gè) weak 指針猛计,所以這個(gè)實(shí)例的值是 CFMutableSet 類型。

剩下我們要做的爆捞,就是在引用計(jì)數(shù)變成 0 的時(shí)候奉瘤,去這個(gè)全局的字典里面,找到所有的 weak 指針煮甥,將其值設(shè)置成 nil盗温。如何做到這一點(diǎn)呢?Friday QA 上介紹了一種類似 KVO 實(shí)現(xiàn)的方式成肘。當(dāng)對(duì)象存在 weak 指針時(shí)卖局,我們可以將這個(gè)實(shí)例指向一個(gè)新創(chuàng)建的子類,然后修改這個(gè)子類的 release 方法艇劫,在 release 方法中吼驶,去從全局的 CFMutableDictionary 字典中找到所有的 weak 對(duì)象( 這里應(yīng)該是找到所有弱引用本對(duì)象的地方,將其置為nil )店煞,并且設(shè)置成 nil蟹演。我摘抄了 Friday QA 上的實(shí)現(xiàn)的核心代碼,如下:

Class subclass = objc_allocateClassPair(class, newNameC, 0);
Method release = class_getInstanceMethod(class, @selector(release));
Method dealloc = class_getInstanceMethod(class, @selector(dealloc));
class_addMethod(subclass, @selector(release), (IMP)CustomSubclassRelease, method_getTypeEncoding(release));
class_addMethod(subclass, @selector(dealloc), (IMP)CustomSubclassDealloc, method_getTypeEncoding(dealloc));
objc_registerClassPair(subclass);

33顷蟀、自己寫(xiě)的 view 成員酒请,應(yīng)該用 weak 還是 strong?

問(wèn)題

從 Storyboard 往編譯器拖出來(lái)的 UI 控件的屬性是 weak 的鸣个,如下所示

@property (weak, nonatomic) IBOutlet UIButton *myButton;

那么羞反,如果有一些 UI 控件我們要用代碼的方式來(lái)創(chuàng)建,那么它應(yīng)該用 weak 還是 strong 呢囤萤?為什么昼窗?

答案

當(dāng) UI 控件是 weak 時(shí),它的引用計(jì)數(shù)是 1涛舍,持有它的是它的 superview澄惊,當(dāng) UI 控件是 strong 時(shí),它的引用計(jì)數(shù)是 2富雅,持有它的有兩個(gè)地方掸驱,一個(gè)是它的 superview,另一個(gè)是這個(gè) strong 的指針没佑。UI 控件并不會(huì)持有別的對(duì)象毕贼,所以,不管是手寫(xiě)代碼還是 Storyboard蛤奢,UI 控件是 strong 都不會(huì)有循環(huán)引用的鬼癣。

weak 變量會(huì)有額外的系統(tǒng)維護(hù)開(kāi)銷的陶贼,如果你沒(méi)有使用它的特別的理由,那么用 strong 的話應(yīng)該更好扣溺。

如果要做 Lazy 加載骇窍,那么也只能選擇用 strong。

當(dāng)然锥余,如果非要用 weak,其實(shí)也沒(méi)什么問(wèn)題痢掠,只需要注意在賦值前驱犹,先把這個(gè)對(duì)象用 addSubView 加到父 view 上,否則可能剛剛創(chuàng)建完足画,它就被釋放了雄驹。

34、實(shí)現(xiàn)一個(gè)嵌套數(shù)組的迭代器

問(wèn)題

1淹辞、給一個(gè)嵌套的 NSArray 數(shù)據(jù)医舆,實(shí)現(xiàn)一個(gè)迭代器類,該類提供一個(gè) next() 方法象缀,可以依次的取出這個(gè) NSArray 中的數(shù)據(jù)蔬将。比如 NSArray 如果是 [1,[4,3],6,[5,[1,0]]], 則最終應(yīng)該輸出:1, 4, 3, 6, 5, 1, 0 央星。

2霞怀、實(shí)現(xiàn)一個(gè) allObjects 方法,可以一次性取出所有元素莉给。

解答

先看第二個(gè)問(wèn)題:

可以實(shí)現(xiàn)一個(gè)遞歸函數(shù)毙石,在函數(shù)中判斷數(shù)組中的元素是否又是數(shù)組,如果是的話颓遏,就遞歸調(diào)用自己徐矩,如果不是數(shù)組,則加入到一個(gè) NSMutableArray 中即可叁幢。下面是示例代碼:

- (NSArray *)allObjects {
    NSMutableArray *result = [NSMutableArray array];
    [self fillArray:_originArray into:result];
    return result;
}

- (void)fillArray:(NSArray *)array into:(NSMutableArray *)result {
    for (NSUInteger i = 0; i < array.count; ++i) {
        if ([array[i] isKindOfClass:[NSArray class]]) {
            [self fillArray:array[i] into:result];
        } else {
            [result addObject:array[i]];
        }
    }
}

第一個(gè)問(wèn)題:

記錄下遍歷的位置滤灯,然后每次遍歷時(shí)更新位置。由于本題中元素是一個(gè)嵌套數(shù)組遥皂,所以我們?yōu)榱擞涗浵挛恢昧ε纾托枰獌蓚€(gè)變量:一個(gè)是當(dāng)前正在遍歷的子數(shù)組,另一個(gè)是這個(gè)數(shù)組遍歷到的位置演训。

在實(shí)現(xiàn)的時(shí)候弟孟,定義了一個(gè)名為 NSArrayIteratorCursor 的類來(lái)記錄這些內(nèi)容,NSArrayIteratorCursor 的定義和實(shí)現(xiàn)如下:

@interface NSArrayIteratorCursor : NSObject

@property (nonatomic) NSArray *array;
@property (nonatomic) NSUInteger index;

@end

@implementation NSArrayIteratorCursor

- (id)initWithArray:(NSArray *)array {
    self = [super init];
    if (self) {
        _array = array;
        _index = 0;
    }
    return self;
}

@end

由于數(shù)組在遍歷的時(shí)候可能產(chǎn)生遞歸样悟,就像實(shí)現(xiàn) allObjects 方法那樣拂募。所以我們需要處理遞歸時(shí)的 NSArrayIteratorCursor 的保存庭猩,在實(shí)現(xiàn)的時(shí)候,拿數(shù)組當(dāng)作棧陈症,來(lái)實(shí)現(xiàn)保存遍歷時(shí)的狀態(tài)蔼水。

最終,實(shí)現(xiàn)了一個(gè)迭代器類录肯,名字叫 NSArrayIterator趴腋,用于最終提供 next方法的實(shí)現(xiàn)。這個(gè)類有兩個(gè)私有變量论咏,一個(gè)是剛剛說(shuō)的那個(gè)棧优炬,另一個(gè)是原數(shù)組的引用。

@interface NSArrayIterator : NSObject

- (id)initWithArray:(NSArray *)array;
- (id)next;
- (NSArray *)allObjects;

@end

@implementation NSArrayIterator {
    NSMutableArray *_stack;
    NSArray *_originArray;
}

在初使化的時(shí)候厅贪,初始化遍歷位置的代碼如下:

- (id)initWithArray:(NSArray *)array {
    self = [super init];
    if (self) {
        _originArray = array;
        _stack = [NSMutableArray array];
        [self setupStackWithArray:array];
    }
    return self;
}

- (void)setupStackWithArray:(NSArray *)array {
    NSArrayIteratorCursor *c = [[NSArrayIteratorCursor alloc] initWithArray:array];
    [_stack addObject:c];
}

用遞歸的方式來(lái)處理空數(shù)組的邏輯似乎是寫(xiě)起來(lái)更簡(jiǎn)單的蠢护,邏輯如下:

1、判斷棧是否為空养涮,如果為空則返回 nil葵硕。
2、從棧中取出元素贯吓,看是否遍歷到了結(jié)尾懈凹,如果是的話,則出棧宣决。
3蘸劈、判斷第 2 步是否使棧為空,如果為空尊沸,則返回 nil威沫。
4、終于拿到元素了洼专,這一步判斷拿到的元素是否是數(shù)組棒掠。
   a、如果是數(shù)組屁商,則重新生成一個(gè)遍歷的 NSArrayIteratorCursor 對(duì)象烟很,放到棧中,并且遞歸調(diào)用自己蜡镶。
   b雾袱、如果不是數(shù)組,就把元素返回官还,同時(shí)更新索引到下一個(gè)位置芹橡。

整個(gè)代碼也變得更短更清楚了一些,如下所示:

- (id)next {
    //  1. 判斷棧是否為空望伦,如果為空則返回 nil林说。
    if (_stack.count == 0) {
        return nil;
    }
    // 2. 從棧中取出元素煎殷,看是否遍歷到了結(jié)尾,如果是的話腿箩,則出棧豪直。
    NSArrayIteratorCursor *c;
    c = [_stack lastObject];
    while (c.index == c.array.count && _stack.count > 0) {
        [_stack removeLastObject];
        c = [_stack lastObject];
    }
    // 3. 判斷第2步是否使棧為空,如果為空珠移,則返回 nil弓乙。
    if (_stack.count == 0) {
        return nil;
    }
    // 4. 終于拿到元素了,這一步判斷拿到的元素是否是數(shù)組剑梳。
    id item = c.array[c.index];
    if ([item isKindOfClass:[NSArray class]]) {
        c.index++;
        // 5. 如果是數(shù)組唆貌,則重新生成一個(gè)遍歷的
        //    NSArrayIteratorCursor 對(duì)象,放到棧中, 然后遞歸調(diào)用 next 方法
        [self setupStackWithArray:item];
        return [self next];
    }

    // 6. 如果到了這一步垢乙,說(shuō)明拿到了一個(gè)非數(shù)組的元素,這樣就可以把元素返回语卤,
    //    同時(shí)更新索引到下一個(gè)位置追逮。
    c.index++;
    return item;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市粹舵,隨后出現(xiàn)的幾起案子钮孵,更是在濱河造成了極大的恐慌,老刑警劉巖眼滤,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巴席,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡诅需,警方通過(guò)查閱死者的電腦和手機(jī)漾唉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)堰塌,“玉大人赵刑,你說(shuō)我怎么就攤上這事〕⌒蹋” “怎么了般此?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)牵现。 經(jīng)常有香客問(wèn)我铐懊,道長(zhǎng),這世上最難降的妖魔是什么瞎疼? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任科乎,我火速辦了婚禮,結(jié)果婚禮上丑慎,老公的妹妹穿的比我還像新娘喜喂。我一直安慰自己瓤摧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布玉吁。 她就那樣靜靜地躺著照弥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪进副。 梳的紋絲不亂的頭發(fā)上这揣,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音影斑,去河邊找鬼给赞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛矫户,可吹牛的內(nèi)容都是我干的片迅。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼皆辽,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼柑蛇!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起驱闷,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤耻台,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后空另,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體盆耽,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年扼菠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了摄杂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡娇豫,死狀恐怖匙姜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情冯痢,我是刑警寧澤氮昧,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站浦楣,受9級(jí)特大地震影響袖肥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜振劳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一椎组、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧历恐,春花似錦寸癌、人聲如沸专筷。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)磷蛹。三九已至,卻和暖如春溪烤,著一層夾襖步出監(jiān)牢的瞬間味咳,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工檬嘀, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留槽驶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓鸳兽,卻偏偏與公主長(zhǎng)得像掂铐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子揍异,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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