RxSwift (二)序列核心邏輯分析

@TOC

RxSwift序列核心邏輯

上一篇博客:Rxswift學習之(一)函數響應式編程思想只是簡單的分析了序列的核心邏輯。本篇博客主要針對上一篇做一下更加深入的探討,如果有那些地方分析有誤,還請留言:QQ:282889543,讓我們彼此提高,彼此成就。

總的來說分析Rxswift的核心邏輯還是按照三部曲:創建序列,訂閱序列,銷毀序列。核心思想是萬物皆序列。

1. 序列的創建

Observable可觀察者序列

我們先來看下創建Observable所涉及的類的繼承關系:
如下圖:


針對上面的類圖,簡單分析下類的關系和設計思想:
首先分層實施的很徹底,每一層都只解決一件事情,一層層疊起來結構非常清晰:
AnonymousObservable -> Producer -> Observable -> ObservableType -> ObservableConvertibleType

其次我們簡單分解一下每個類都做了些什么:

  • ObservableConvertibleType:顧名思義即可轉換為Observable 類型協議,方法只有一個asObservable,這有什么好處呢?
  1. 用戶不需要關注其具體是哪個類型對象
  2. 讓用戶更多的關注其核心功能
  • ObservableType:也是個協議,繼承了ObservableConvertibleType協議的asObservable,它提供抽象方法subscribe,即我們常說的訂閱,只有外部訂閱了該對象,才能真正實現對該對象進行觀察。
  • Observable:真正的類,可以稱之為元類,對于用戶來說Observable 的功能是完整的,因為它已經具備了所有的用戶所需要的功能,盡管有些方法并沒有得到實現仍是抽象方法。
    Producer: 它繼承了Observable的所有方法,并實現subscribe 方法
  • AnonymousObservable:它繼承了Producer的所有方法,并且增加了屬性let _subscribeHandler: SubscribeHandler用來保存創建序列時傳入的閉包,也就相對于擁有了調用這個序列的能力,此外它還實現run方法,這也是創建序列最核心關鍵的方法。在run()方法中它創建一個AnonymousObservableSink final private類的對象,而這個對象sink可以稱之為管子,它類似于manager的角色,擁有序列和訂閱,銷毀能力。這里有兩個疑惑:

問題1. AnonymousObservableSink為什么要定義成final private類,不能被繼承,也不能被外部訪問?
問題2. 創建的Observable是如何關聯到訂閱的?

這兩個問題我們后面再分析。

最后,我們總結一下設計思想:

事實上用戶所使用的 Observable ,都是 Producer 的子類和AnonymousObservable平行的子類,只不過用戶不需要關心其具體實現罷了
每一個類似AnonymousObservable的類,還有一個與之相關的類AnonymousObservableSink,Sink即管道,所有這些組合起來才能讓其真正運行起來,AnonymousObservableSink同時擁有序列,訂閱功能,類似于我們項目中經常用的manager角色。
整個設計向上通過組合協議的方式描述其特性,向下通過子類化的方式屏蔽其實現細節,類似于工廠模式,這樣的類也可以叫類簇。

序列創建的流程

通過上面類繼承關系,其實我們不難理解序列的創建流程,它確實也是只有比較簡單的幾部,寥寥幾行代碼就搞定了,難點是上面拋出的幾個問題:

下面我們將通過一個簡單的Rxswift的實例來分析一下序列的創建,訂閱,銷毀直接的流程和關系。

實例1

    //1. 創建序列
   let ob = Observable<Any>.create { (obserber) -> Disposable in
            // 3:發送信號
            obserber.onNext("kyl發送了信號")
            obserber.onCompleted()
            return Disposables.create()
        }
    
        // 2:訂閱信號
        let _ = ob.subscribe(onNext: { (text) in
            print("訂閱到:\(text)")
        }, onError: { (error) in
            print("error: \(error)")
        }, onCompleted: {
            print("完成")
        }) {
            print("銷毀")
        }

上面實例1 的這段代碼可以用酷C老師的一個圖來清晰的表達:

從上面的代碼和關系圖,我們可能會產生這樣一個疑惑:

問題3: 創建的ob序列,僅僅只是通過ob.subscribe()訂閱了一下,為什么我們在ob創建時的尾隨閉包(我們這里給個名字叫閉包A)里面調用了obserber.onNext("kyl發送了信號")這個代碼,我們就可以訂閱到let _ = ob.subscribe(onNext: { (text) in print("訂閱到:\(text)") } 這里會打印:”訂閱到:kyl發送了信號“。我們沒有看見他們之間有任何關聯,怎么ob發送消息,subcribe()的onNext閉包就可以觸發呢,這是為什么呢?

我們可以這里可以簡單推理下:ob.subscribe()這個訂閱方法肯定做了一些事情,在某個地方調用了閉包A,才能實現這個功能。具體是怎么樣實現的呢?下面我們將通過分析源碼來解答這個疑惑。

從上面的代碼我們可以知道,創建序列就一行代碼:let ob = Observable<Any>.create { (obserber) -> 而這一行代碼其實是做了好多事情的。

首先我們通過一個流程圖來初略的了解一下序列創建流程:

創建序列的Rxswift原碼很簡單,從上圖可以看出,直接一行代碼return AnonymousObservable(subscribe)就結束了,這里我們們并沒有找到我們需要的答案,甚至我們有點越來越暈感覺。

  • AnonymousObservable類源碼
final private class AnonymousObservable<Element>: Producer<Element> {
    typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable

    let _subscribeHandler: SubscribeHandler

    init(_ subscribeHandler: @escaping SubscribeHandler) {
        self._subscribeHandler = subscribeHandler
    }

    override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
        let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
        let subscription = sink.run(self)
        return (sink: sink, subscription: subscription)
    }
}

我們先做個深呼吸,放輕松,此路不通那我們來嘗試分析其他方向,不能在一棵樹上吊死。下面我們來分析一下訂閱的流程。

2.訂閱

回顧上面實例1中的訂閱代碼:let _ = ob.subscribe(onNext: { (text) in這行代碼又做了些什么事情呢?下面我們通過源碼來深入分析一下:

  • Rxswift訂閱subscribe()的源碼如下:
  public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
        -> Disposable {
            
            ... 上面代碼不是我們要分析的重點,...表示忽略了此次的一段源碼
            /*注意,此次定義了一個AnonymousObserver()對象,以參數的形式,
            構造方法里面傳入了一個尾隨閉包eventHandler,
            在這個閉包里面,當收到event的不同事件,
            會觸發并調用,我們 `let _ = ob.subscribe(onNext: { (text) in` 這個方法傳入閉包
            */
            let observer = AnonymousObserver<E> { event in
          
                ...
                
                switch event {
                case .next(let value):
                    onNext?(value) //調用訂閱時傳入的ob.subscribe(onNext:閉包
                case .error(let error):
                    if let onError = onError {
                        onError(error)//調用訂閱時傳入的ob.subscribe(onError:閉包
                    }
                    else {
                        Hooks.defaultErrorHandler(callStack, error)
                    }
                    disposable.dispose()
                case .completed:
                    onCompleted?()//調用訂閱時傳入的ob.subscribe(onCompleted:閉包
                    disposable.dispose()
                }
            }
            return Disposables.create(
                self.asObservable().subscribe(observer),
                disposable
            )/*這里直接返回了Disposables對象,用來釋放資源,
            在它的構造函數里面直接調用了self.asObservable().subscribe(observer),
            而asObservable()就是我們創建的序列ob,也就是ob.subscribe(),
            并傳入了,在這段代碼里面創建的局部變量let observer = AnonymousObserver<E>,*/
    }

通過上面源碼我們可以知道:subscribe()這個方法,以參數的形式傳入了onNext()閉包,onError()閉包,onComplete()閉包,在函數里面創建了一個AnonymousObserver對象observer,這個對象創建的時候傳入了一個閉包,當收到不同event事件時,會分別調用我們subscribe()傳入的onNext,onError,onComplete這三個閉包。最重要一點是return Disposables.create( self.asObservable().subscribe(observer), disposable )這句代碼調用了我們真正的subscribe()函數,并以參數的形式傳入了AnonymousObserver對象,self.asObservable()就是我們create()函數創建的序列ob, 而到此處我們可以清晰的看到,我們訂閱時傳入參數閉包和我們創建的ob建立了一個鏈條。

這里我們又有一個疑問:self.asObservable()為什么就是我們create()函數返回的ob呢?

要解答這個問題,我需要回顧一下上面分析的Observable類的繼承關系:Observable -> ObservableType -> ObservableConvertibleType 即Observable繼承ObservableType協議,ObservableType又繼承ObservableConvertibleType協議,而我們的ObservableConvertibleType提供了抽象方法asObservable(),我們Observable類中實現了asObservable()這個方法,它直接返回self就它自己。

下面通過源碼來證實:

///
/// It represents a push style sequence.
public class Observable<Element> : ObservableType {

    ...
    
    public func asObservable() -> Observable<E> {
        return self
    }
    
    ...
}

分析了Rxswift訂閱subscribe()的源碼感覺非常nice, 我們找到了我們ob 創建時傳入的閉包和我們訂閱時的閉包存在了一條鏈條關系,也就是只要ob發送了消息,那我們的訂閱者一定可以按照這個鏈條收到消息。但是我們還是不知道到底是怎么調用的,怎么觸發的。

而且我們注意到self.asObservable().subscribe(observer)也就是AnonymousObservable調用了subscribe()方法,但是在AnonymousObservable類中我們并沒有找到subscribe()的定義,所以我們需要來看他的父類Producer

  • Producer的源碼如下:
class Producer<Element> : Observable<Element> {
    override init() {
        super.init()
    }

    override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
        if !CurrentThreadScheduler.isScheduleRequired {
            // The returned disposable needs to release all references once it was disposed.
            let disposer = SinkDisposer()
            /*重點在這里了,這里調用了run()方法,一切疑惑都清晰了,我們知道了run()調用時傳入了observer,并且創建了sink管子,而這個管子具備了序列的功能,可以調用on()方法。
            */
            let sinkAndSubscription = self.run(observer, cancel: disposer)
            disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

            return disposer
        }
        else {
            return CurrentThreadScheduler.instance.schedule(()) { _ in
                let disposer = SinkDisposer()
                let sinkAndSubscription = self.run(observer, cancel: disposer)
                disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

                return disposer
            }
        }
    }

    func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
        rxAbstractMethod()
    }
}

果然不出我們所料,在Producer中我們找到了subscribe()的方法定義,到此我們可以總結出很清晰的幾條線索了

  • (1)通過前面的類繼承關系可以知道是Producer實現了ObservableType協議的subscribe()方法。在這個方法里面調用了self.run(observer, cancel: disposer)
  • (2) self.run()實際上就是AnonymousObservable.run(), 這這個方法里面做了三件事情:
override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
//1.創建了一個sink管道對象,并將observer也就create()創建
//序列時傳入的閉包傳給了sink
        let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
        //2. sink調用自己的run()方法,并把AnonymousObservable作為參數傳入。
        let subscription = sink.run(self)
        //返回一個元組,包含sink管道信息。
        return (sink: sink, subscription: subscription)
    }
  • (3)AnonymousObservableSink類中run()方法中調用parent._subscribeHandler(AnyObserver(self)) 其中parent就是我們(2)中sink.run(self)傳入的self,也就是AnonymousObservable對象;并且我們前面已經知道_subscribeHandler就是創建序列時保存的那個通過create()函數參數傳入的 閉包:let ob = Observable<Any>.create { (obserber) -> Disposable in // 3:發送信號 obserber.onNext("kyl發送了信號") obserber.onCompleted() return Disposables.create() }。 現在已經很清晰了parent._subscribeHandler(AnyObserver(self)) 執行閉包,這行代碼就會調用obserber.onNext("kyl發送了信號")這個行代碼。
  • 現在我們可以通過一個流程圖來總結我們代碼執行的流程:

上面的訂閱序列流程分析:我們弄明白了從訂閱序列到調用create()函數時傳入的參數閉包調用的邏輯,但是這個閉包發送onNext()信號后,怎么到訂閱消息的onNext()閉包我們還不是很清晰。因此我們需要分析AnonymousObserver

我們先來看下AnonymousObserver

  • AnonymousObserver源碼定義如下:
final class AnonymousObserver<ElementType> : ObserverBase<ElementType> {
    typealias Element = ElementType
    
    typealias EventHandler = (Event<Element>) -> Void
    
    private let _eventHandler : EventHandler
    
    /*構造函數,保存了EventHandler尾隨閉包*/
    init(_ eventHandler: @escaping EventHandler) {
#if TRACE_RESOURCES
        _ = Resources.incrementTotal()
#endif
        self._eventHandler = eventHandler
    }

    //覆寫了onCore方法,調用了EventHandler閉包
    override func onCore(_ event: Event<Element>) {
        return self._eventHandler(event)
    }
    
#if TRACE_RESOURCES
    deinit {
        _ = Resources.decrementTotal()
    }
#endif
}

AnonymousObserver源碼中我們并沒有找到onNext()方法,那我們只能沿著它的繼承鏈往上查找,這里需要了解一下類的繼承關系:

  • AnonymousObserver的繼承關系:

通過分析類的繼承關系,我們得知:這樣一個關系鏈:

AnonymousObserver對象的on()方法會調用onCore()方法,ObserverType里面有onNext,onError,onComplete方法。但是on()是如何調用的,何時調用的呢?

要解決這個疑問,我們需要再次回到我們創建序列的代碼:

public static func create(_ subscribe: @escaping (AnyObserver<E>) -> Disposable) -> Observable<E> {
        return AnonymousObservable(subscribe)
    }

創建序列的create()方法傳入了一個subscribe閉包,并返回了AnonymousObservable對象。其中subscribe閉包就是我們序列創建時參數形式傳入 閉包。并且AnonymousObservable初始化時將這個閉包保存起來了self._subscribeHandler = subscribeHandler AnonymousObservable 有一個run()方法,run方法里面創建了一個AnonymousObservableSink對象sink,具體源碼如下:

final private class AnonymousObservable<Element>: Producer<Element> {
    typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable

    let _subscribeHandler: SubscribeHandler

    init(_ subscribeHandler: @escaping SubscribeHandler) {
        self._subscribeHandler = subscribeHandler
    }

    override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
        let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
        let subscription = sink.run(self)
        return (sink: sink, subscription: subscription)
    }
}

分析了這么久,繞了一圈,終于發現關鍵就在AnonymousObservableSink管子這個對象里面了。sink這是個神奇的管子。它就保存了序列,也保存了訂閱,還保存了用于銷毀的disposed 也就是同時擁有了創建序列,訂閱序列,銷毀序列功能。

我們來分析下AnonymousObservableSink的源碼:

final private class AnonymousObservableSink<O: ObserverType>: Sink<O>, ObserverType {
    typealias E = O.E
    //這里的Parent就是我們上面分析的AnonymousObservable,非常重要
    typealias Parent = AnonymousObservable<E>

    // state
    private let _isStopped = AtomicInt(0)

    #if DEBUG
        fileprivate let _synchronizationTracker = SynchronizationTracker()
    #endif

// 構造方法,傳入了observer序列,和Cancelable
    override init(observer: O, cancel: Cancelable) {
        super.init(observer: observer, cancel: cancel)
    }

//這里實現 了ObserverType協議的on()方法
    func on(_ event: Event<E>) {
        #if DEBUG
            self._synchronizationTracker.register(synchronizationErrorMessage: .default)
            defer { self._synchronizationTracker.unregister() }
        #endif
        switch event {
        case .next:
            if load(self._isStopped) == 1 {
                return
            }
            //調用了父類的發布,self.forwardOn()會調用自己的on()方法
            self.forwardOn(event)
        case .error, .completed:
            if fetchOr(self._isStopped, 1) == 0 {
                self.forwardOn(event)
                self.dispose()
            }
        }
    }

    func run(_ parent: Parent) -> Disposable {
    /*調用了_subscribeHandler閉包,這個閉包就是我們之前創建序列時傳入閉包。
    parent就是傳入進來的序列,這里序列的閉包里傳入了self并且強轉為AnyObserver
    這里將self傳給了閉包_subscribeHandler,這樣_subscribeHandler也就具備了subcribe的能力。
    */
        return parent._subscribeHandler(AnyObserver(self))
    }
}

其中Sink類的源碼如下:

class Sink<O : ObserverType> : Disposable {
    fileprivate let _observer: O
    fileprivate let _cancel: Cancelable
    fileprivate let _disposed = AtomicInt(0)

    #if DEBUG
        fileprivate let _synchronizationTracker = SynchronizationTracker()
    #endif

    init(observer: O, cancel: Cancelable) {
#if TRACE_RESOURCES
        _ = Resources.incrementTotal()
#endif
        self._observer = observer
        self._cancel = cancel
    }

    final func forwardOn(_ event: Event<O.E>) {
        #if DEBUG
            self._synchronizationTracker.register(synchronizationErrorMessage: .default)
            defer { self._synchronizationTracker.unregister() }
        #endif
        if isFlagSet(self._disposed, 1) {
            return
        }
        //這里調用了傳入observer.on()方法,
        self._observer.on(event)
    }

    final func forwarder() -> SinkForward<O> {
        return SinkForward(forward: self)
    }

    final var disposed: Bool {
        return isFlagSet(self._disposed, 1)
    }

    func dispose() {
        fetchOr(self._disposed, 1)
        self._cancel.dispose()
    }

    deinit {
#if TRACE_RESOURCES
       _ =  Resources.decrementTotal()
#endif
    }
}

從源碼分析我們得知:

  • 我們的sink保存了我們的序列,當我們調用ob.onNext()發送信號時,由于我們的sink已經持有了ob, 這樣sink會調用on()方法,在on()方法里面會調用self.forwardOn(event),而在fowardOn()里面會調用self._observer.on(event)。這樣我的疑問就解決了,答案就是sink調用了on()方法。

  • 這里我們再來總結一下總的流程:

  1. 創建序列時create()返回了一個ob, 這個ob就是序列,創建的時候傳遞了一個閉包A。在閉包A中調用了ob.onNext()發送了信號。
  2. 訂閱序列時調用ob.subscribe()方法,這個方法會創建一個AnonymousObserver對象,并調用了self.asObservable().subscribe(observer)
  3. self.asObservable()實際就是我們的ob, 也就是ob調用了subscribe().而AnonymousObserver中沒有找到subscribe()。
  4. 我們在AnonymousObserver的父類中找到了subscribe(),發現subscribe()調用了AnonymousObserver的run()方法。
  5. 在AnonymousObserver的run()方法中,創建了一個管子sink,并調用了sink.run(self),sink是AnonymousObservableSink的對象,而在sink的run()方法中parent._subscribeHandler(AnyObserver(self))調用了創建序列時保存的閉包A (parent就是AnonymousObserver),這樣就解釋了訂閱時,回調了A閉包的原因。
  6. 至于怎么調用onNext()方法也是通過sink來實現的。
  7. sink已經持有了ob ,當我們在A閉包里面調用ob.onNext()發送信號時,實際會通過sink.on()來調用。首先sink.on()會調用forwardOn().
  8. 在forwardOn()中會調用self._observer.on(event)。
  9. _observer.on()會調用_observer.onCore()
  10. _observer.onCore(event)會根據event的類型判斷是調用onNext(),onError(),onComplete()中間一個,由于我們傳遞的是onNext事件,所以會調用onNext() ,而這個_observer.onNext()會調用我們訂閱時傳入閉包subscribe(onNext:).
  11. 為什么回調的原因是:
public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
        -> Disposable {
            
            ... 上面代碼不是我們要分析的重點,...表示忽略了此次的一段源碼
            /*注意,此次定義了一個AnonymousObserver()對象,以參數的形式,
            構造方法里面傳入了一個尾隨閉包eventHandler,
            在這個閉包里面,當收到event的不同事件,
            會觸發并調用,我們 `let _ = ob.subscribe(onNext: { (text) in` 這個方法傳入閉包
            */
            let observer = AnonymousObserver<E> { event in
          
                ...
                
                switch event {
                case .next(let value):
                    onNext?(value) //調用訂閱時傳入的

這里調用ob.subscribe()的時候,我們創建了AnonymousObserver和我們subscribe()傳入的onNext()閉包做了一個綁定,當AnonymousObserver.onNext()調用的時候必定會回調subscribe()傳入的onNext()閉包。而10中的_observer對象指的就是let observer = AnonymousObserver

  • 還是通過這張圖來解釋最簡潔:

3. 銷毀

RxSwift給我們的展示的設計思維

iOS 常用設計模式

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容