2020年炉擅,SwiftUI 的重大改變及核心優(yōu)勢(shì)

收錄:原文地址
原作者:姜沂(傾寒)

前言


SwiftUI 是蘋果公司于 2019 年推出的 Apple Platform 的新一代聲明式布局引擎灿椅,筆者于去年第一時(shí)間升級(jí) Beta 嘗鮮全家庭,并在短時(shí)間內(nèi)迅速落地了基于 SwiftUI 的內(nèi)部 APP正蛙, 也分享了幾篇關(guān)于 SwiftUI 的文章抚太, 但 SwiftUI 1.0 基本沒有任何公司敢用在正式上線的主 APP 上栋荸,API 在 Beta 版本之間各種廢棄,UI 樣式經(jīng)常不兼容凭舶,大列表性能差,彼時(shí)都標(biāo)識(shí)著 SwiftUI 還稱為一個(gè) Toy Framewrok.

隨著 WWDC 20 相關(guān)新特性和介紹視頻的釋出爱沟,都明確的宣告著 SwiftUI 元年已經(jīng)到了帅霜,SwiftUI 已經(jīng)成長(zhǎng)為新時(shí)代的布局引擎。

以下從幾個(gè)方面分享關(guān)于 SwiftUI 的重大改變及核心優(yōu)勢(shì)呼伸。


PS: 需要讀者對(duì) Swift 及 SwiftUI 1.0 有一定熟悉身冀。

SwiftUI Apps


蘋果在最近幾年的動(dòng)作中一直在搞 Apple Platform 統(tǒng)一的事情钝尸,從最近幾年的 iPad 多任務(wù) 多窗口,到 Mac Catalyst 再到今年更進(jìn)一步直接推出了 Apple silicon 芯片更是從硬件上做到了真正統(tǒng)一(話外音:你們?cè)谲浖贤娴哪切┛缙脚_(tái)的都是小玩意搂根,硬件才是王道)珍促。

還提供了 Rosetta2 Universal2 幫助開發(fā)者基本無成本的遷移到新平臺(tái)上。但是作為軟件工程師還是要更多的關(guān)注軟件生態(tài)的變化剩愧。首先了解下創(chuàng)建 APP 時(shí)的變化

可以看到創(chuàng)建新工程時(shí)有了一套全新的模板基于 SwiftUI App Lifecycle 的跨平臺(tái)項(xiàng)目猪叙。

代碼也從原本的基于 UI/NS HostViewController 變成了基于 APP 的聲明式描述,下面是代碼的前后對(duì)比.

  • Before
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        let contentView = ContentView()
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }
}
  • After
import SwiftUI 
@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

其中@main 是Swift 5.1 新增的 Attribute 標(biāo)記了應(yīng)用程序的入口點(diǎn)仁卷,更多請(qǐng)參看 SE-0281-main-attribute.md

乍看好像只有代碼精簡(jiǎn)了不少穴翩,很多人會(huì)認(rèn)為這個(gè)簡(jiǎn)潔程度還不如Flutter 的 main() => runApp(MyApp());.

但最重要的變化是這是第一次跨平臺(tái)代碼,完全無需引入任何 UIKit APPKit WatckKit 等相關(guān)Framewok, 即可直接運(yùn)行在不同平臺(tái)上锦积。這意味著我們后續(xù)在UI布局系統(tǒng)上可以逐漸擺脫對(duì)傳統(tǒng)命令式 UI 編程的依賴芒帕。達(dá)到真正的平臺(tái)無關(guān)。

SwiftUI 將整個(gè)原有的平臺(tái)差異部分抽象為 App 和 Scene丰介,對(duì)于一個(gè) mac/iOS/iPad/watch/tv/..應(yīng)用背蟆,來說 App 代表了整個(gè)應(yīng)用,Scene 代表了與 Window 相關(guān)的多窗口哮幢,有些設(shè)備只有一個(gè) Scene 有些則有多個(gè)带膀,雖然不同的 OS 確實(shí)存在差異,但是在語義層面達(dá)到了一致家浇。

其次一個(gè)沒有歷史包袱的 APP本砰,也可以完整的從 Swift APP lifecycle 風(fēng)格式的模板開始,無需再和傳統(tǒng)的 UIKit/APPKit 等混合钢悲。這也意味著可以達(dá)到 APP 完全 Declared and State-Driven点额。

Viusal Editing


Preview

在傳統(tǒng)的利用 DSL 可視編程框架或者平臺(tái),諸如 Web Flutter 等技術(shù)莺琳,都是開發(fā)者編寫好對(duì)應(yīng)的代碼还棱,運(yùn)行在對(duì)應(yīng)的平臺(tái)或者調(diào)試工具上。SwiftUI 作為蘋果最重要的軟件層戰(zhàn)略框架惭等,更是和 Xcode 深度結(jié)合珍手,在運(yùn)行之前就可以完整的預(yù)覽你所編寫的界面。

強(qiáng)大的 Preview 可以讓你既可以從編寫 DSL 到立即預(yù)覽效果辞做,也可從預(yù)覽的 Canvas 畫布中直接修改效果在代碼編輯器中生成代碼琳要,這對(duì)于日常開發(fā)的效率有非常大的提高,尤其是在 UI 微調(diào)時(shí)秤茅,效果尤為突出稚补。

Xcode12 可以在 Canvas 上同時(shí)預(yù)覽多個(gè)不同設(shè)備環(huán)境的界面,也可以直接投射到真實(shí)的設(shè)備上來預(yù)覽。

對(duì)于日常開發(fā)來說框喳,編寫一個(gè)UI界面通常依賴外部的網(wǎng)絡(luò)/磁盤/其他數(shù)據(jù)课幕,才能正常的構(gòu)建厦坛,這也造成了UI開發(fā)雖然是開發(fā)中較為簡(jiǎn)單的一步,但同時(shí)也是最耗時(shí)的一步乍惊,有了預(yù)覽功能杜秸,可以把很多繁瑣的工作前置解決掉,對(duì)于研發(fā)效率會(huì)有非常大的提高润绎。

Xcode Library

在編寫真實(shí)項(xiàng)目中撬碟,一個(gè)公司的 APP UI 包含成百上千種風(fēng)格的 View 組件,對(duì)于 UI 組件豐富的產(chǎn)品凡橱,如果一個(gè)新需求可以由現(xiàn)有的組件組合小作,那么需求交付的時(shí)間也會(huì)大大縮短。

但是對(duì)于一個(gè)大型的開發(fā)團(tuán)隊(duì)而言稼钩,一個(gè)開發(fā)同學(xué)是很難知道公司內(nèi)到底有多少種組件庫(kù)顾稀,而且即便知道有某種組件庫(kù),開發(fā)同學(xué)初期看到的也是代碼坝撑,一般需要書寫一定的 Demo 才可以用眼睛感知到這個(gè)組件到底是否是我想要的静秆。

在 Xcode 12 中提供了更強(qiáng)大的工具,一個(gè)自定義組件巡李,只需要遵守一個(gè) LiberyContentProvider 協(xié)議就可被Xcode識(shí)別抚笔,可以像系統(tǒng)控件一樣直接從 Xcode 里面識(shí)別并預(yù)覽。對(duì)于一個(gè)大型團(tuán)隊(duì)來說侨拦,此功能可以大大提高找尋組件和查看組件樣式的效率殊橙。

// Without trailing closure:
        UIView.animate(withDuration: 0.3, animations: {
          self.view.alpha = 0
        }, completion: { _ in
          self.view.removeFromSuperview()
        })
        // With trailing closure
        UIView.animate(withDuration: 0.3, animations: {
          self.view.alpha = 0
        }) { _ in
          self.view.removeFromSuperview()
        }
        // Multiple trailing closure arguments
        UIView.animate(withDuration: 0.3) {
          self.view.alpha = 0
        } completion: { _ in
          self.view.removeFromSuperview()
        }


DSL

隨著 Swift5.3 和 SwiftUI2.0 的推出,SwiftUI 在 DSL 上也更富有表現(xiàn)力狱从, Swift 支持了多重尾閉包語法和在 ViewBuilde 里面支持 Switch Case 語句膨蛮。

Multiple Trailing Closures

雖然社區(qū)對(duì)多重尾閉包的討論上一直存在爭(zhēng)議問題,但最終 Swift5.3 還是接受并實(shí)現(xiàn)了季研,在普通命令式編程的地方使用會(huì)有一定的困惑性敞葛,但是在 SwiftUI 中 DSL 也更有聲明式的味道。

 // Without trailing closure:
        UIView.animate(withDuration: 0.3, animations: {
          self.view.alpha = 0
        }, completion: { _ in
          self.view.removeFromSuperview()
        })
        // With trailing closure
        UIView.animate(withDuration: 0.3, animations: {
          self.view.alpha = 0
        }) { _ in
          self.view.removeFromSuperview()
        }
        // Multiple trailing closure arguments
        UIView.animate(withDuration: 0.3) {
          self.view.alpha = 0
        } completion: { _ in
          self.view.removeFromSuperview()
        }

Switch Case Support

在 SwiftUI 的 ViewBuilder DSL體系中也支持了 Switch case 語法与涡。

var body: some View {
            switch c {
            case .a:
                return Text("A")
            case .b:
                return Text("B")
            case .c:
                return Text("C")
            }
        }

Data Flow


在使用傳統(tǒng)命令式編程編寫 UI 代碼時(shí)惹谐,開發(fā)者需要手動(dòng)處理 UIView 和 數(shù)據(jù)之間的依賴關(guān)系,每當(dāng)一個(gè) UIView 使用了外部的數(shù)據(jù)源驼卖,就表明了 UIView 對(duì)外部的數(shù)據(jù)產(chǎn)生了依賴氨肌,當(dāng)一個(gè)數(shù)據(jù)產(chǎn)生變化時(shí),如果意外的沒有同步UIView的狀態(tài)酌畜,那么 Bug 就產(chǎn)生了儒飒。

處理簡(jiǎn)單的依賴關(guān)系是可控的,但是在真實(shí)項(xiàng)目中檩奠,視圖之間的依賴關(guān)系是非常復(fù)雜的桩了,假設(shè)一個(gè)視圖只有 4 種狀態(tài),組合起來就有 16 種埠戳,再加上時(shí)序的不同井誉,情況就更加復(fù)雜。

人腦處理狀態(tài)的復(fù)雜度是有限的整胃,狀態(tài)的復(fù)雜度一旦超過人腦的復(fù)雜度颗圣,就會(huì)產(chǎn)生大量的 Bug,并且修掉了這個(gè)產(chǎn)生了新的Bug屁使。

那么 SwiftUI 是如何解決這個(gè)問題的在岂?

SwiftUI 的框架提供了幾個(gè)核心概念:

  1. 統(tǒng)一的 body 屬性,SwiftUI 自動(dòng)從當(dāng)前 App 狀態(tài)集自動(dòng)生成基于當(dāng)前狀態(tài)的快照 View蛮寂。

  2. 統(tǒng)一的數(shù)據(jù)流動(dòng)原語蔽午。

關(guān)于 SwiftUI 中的 Data Flow 是如何消除視圖和狀態(tài)不一致的,請(qǐng)參考去年撰寫的文檔 系列文章《深度解讀SwiftUI 背后那些事兒》

今年 SwiftUI 2.0 新增的 StateObject 數(shù)據(jù)流原語讓 SwiftUI 在重復(fù)創(chuàng)建 View 時(shí)避免重復(fù)創(chuàng)建 ObservedObject 從而提高 View 重建的性能酬蹋。

SceneStorage 和 APPStorgae 讓一些可持久化的數(shù)據(jù)變得更加簡(jiǎn)單且具有語義化及老。

New Controls


前面提到的,新增的 DSL 語法 SwiftUI App Lifecycle范抓,以及 Xcode Library Preview 其實(shí)本質(zhì)上都是對(duì)去年 SwiftUI 1.0 錦上添花的新擴(kuò)展骄恶。

真正重要的是今年新增的各類新控件,其中通過導(dǎo)出來自 Xcode11.5 和 Xcode12.0 beta 版本的 Swift 聲明文件匕垫,可以觀察到整個(gè)聲明文件從原來的 10769 行增加到 20564行僧鲁。

新增了約 87 個(gè) struct 16 個(gè) protocol。有了這些豐富的組件才可以更好的構(gòu)建我們的 APP 象泵。

大列表組件

在任何一款 APP 中都會(huì)存在類似大列表組件寞秃,如淘寶 APP 里面的某家店鋪里面商品列表流,首頁(yè)的信息流单芜,都是具有超長(zhǎng)內(nèi)容的列表頁(yè)數(shù)據(jù)蜕该。對(duì)于長(zhǎng)列表頁(yè)來說,過長(zhǎng)的 UI 頁(yè)面會(huì)導(dǎo)致過多的內(nèi)存占用洲鸠,在用戶的設(shè)備中堂淡,內(nèi)存是最為重要的指標(biāo),對(duì)于目前國(guó)內(nèi)的 APP 市場(chǎng)扒腕,低端手機(jī)仍然占據(jù)大量的市場(chǎng)绢淀,對(duì)于這些設(shè)備來說,一旦內(nèi)存超標(biāo)瘾腰,APP 就很容易 OOM皆的,這會(huì)導(dǎo)致用戶體驗(yàn)非常差,在現(xiàn)有競(jìng)爭(zhēng)關(guān)系激烈的市場(chǎng)環(huán)境下蹋盆,體驗(yàn)差意味著會(huì)失去用戶费薄。

對(duì)于傳統(tǒng)的命令式編程來說硝全,我們可以主動(dòng)控制 UITableViewCell 的重用,自建緩沖池等一系列手段去優(yōu)化我們的 APP 內(nèi)存占用楞抡,但是對(duì)于 SwiftUI 1.0 來說伟众,系統(tǒng)提供的控件并沒有有效的辦法去讓我們控制頁(yè)面的渲染,對(duì)于大列表頁(yè)面就容易出現(xiàn)內(nèi)存占用過高的問題召廷。

SwiftUI 2.0 推出了 LazyHStack 和 lazyVStack 加上 List 渲染模式默認(rèn)就是 Lazy 的直接解決了最大的性能問題凳厢。

筆者以去年使用 SwiftUI 編寫的 Emas App 為例,當(dāng)列表頁(yè)(并無大圖)加載到 500個(gè)時(shí)竞慢, APP 使用內(nèi)存已經(jīng)達(dá)到了將近 360MB 先紫。而只需要切換到 Xcode12 API 調(diào)整為到 LazyVStack 內(nèi)存占用直接降低 300MB 。

Widget and Clips


蘋果與 WWDC 20 推出的 WidgetKit 支持的 API 是 SwiftUI Only筹煮,雖然已經(jīng)可以混合部分UIkit 里面的View遮精,但相信沒有歷史包袱 最低支持版本為 iOS14 的 Widget 沒有人會(huì)選擇笨重的命令式 API。
同理 Clips 也一樣寺谤。

這里因?yàn)槠蚓筒蛔稣归_仑鸥,后續(xù)會(huì)有專門的文章分析相關(guān)技術(shù)。

Swift & SwiftUI 的機(jī)會(huì)在哪里变屁?


筆者曾經(jīng)在公司推動(dòng)集團(tuán)升級(jí)了基建眼俊,支持了 Swift 開發(fā)環(huán)境也在淘寶落地了一些場(chǎng)景,但是集團(tuán)內(nèi)一直有一些質(zhì)疑的聲音粟关, 引入 Swift 到底有什么用疮胖?

SwiftUI 又是 N 年后才可以用上的小玩意,Objective-C 不夠用嗎闷板?現(xiàn)在筆者可以回答這些質(zhì)疑的聲音澎灸, Swift 未來的機(jī)會(huì)在 效率,體驗(yàn)和蘋果的技術(shù)紅利遮晚。

效率

從研發(fā)效率上來說性昭, Swift 對(duì)比 Objective-C 的精簡(jiǎn)程度不言而喻,筆者在淘寶 APP 上線的模塊代碼量下降了 40 %县遣。 但更進(jìn)一步糜颠,如果編寫 UI 界面從 UIKit 轉(zhuǎn)向了 SwiftUI 代碼量直接少了不止一倍。更少的代碼意味著更快的交付萧求,在目前競(jìng)爭(zhēng)激烈的市場(chǎng)會(huì)有更多的試錯(cuò)場(chǎng)景其兴。關(guān)于使用 UIKit 編寫代碼轉(zhuǎn)向 SwiftUI 的代碼量對(duì)比,讀者可以參考開源 APP MovieSwiftUI 直觀了解夸政。

體驗(yàn)

讀者可能比較困惑對(duì)于切換語言和框架元旬,對(duì)體驗(yàn)看上去沒有任何幫助,但事實(shí)真是這樣嗎?

首先引入 Swift 后匀归,由于 Swift 語言設(shè)計(jì)之初便對(duì)安全性列為最重要的目標(biāo)坑资,Swift的引入會(huì)讓代碼盡可能的減少未定義的行為,減少 Crash 意味著APP的穩(wěn)定性提高穆端,體驗(yàn)自然更佳盐茎。

其次雖然 Swift 同樣的語言出于對(duì)安全性考慮編譯處理的指令會(huì)比 Objective-C 更多,但是如果UI部分都用 SwiftUI 來寫呢徙赢?

更少的代碼意味者更小的包大小,目前國(guó)內(nèi)巨頭 APP iOS 端 APP 包大小都朝著 200 MB 奔去探越,如果能減少更多的代碼對(duì)包大小也可以在 200MB 的限制下承載更多而業(yè)務(wù)狡赐。對(duì)用戶的體驗(yàn)也有較大的提升。

更進(jìn)一步由于 Swift 選擇使用值類型構(gòu)建整個(gè)APP钦幔,值類型的有點(diǎn)在于更扁平化的內(nèi)聯(lián)數(shù)據(jù)結(jié)構(gòu)去分配內(nèi)存枕屉,而不是使用更多間接指針引用,減少了大量不必要的堆內(nèi)存消耗鲤氢,意味著整體內(nèi)存使用量的降低搀擂。對(duì)整個(gè) APP 的穩(wěn)定性也有較大的提高。

? 蘋果的選擇

Swift 做為蘋果的戰(zhàn)略語言已經(jīng)發(fā)展的越來越壯大卷玉,自 2019 年 Swift ABI 穩(wěn)定后哨颂,蘋果在 Swift 的投入越來越大。我們可以進(jìn)入 /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/swift , /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks , https://github.com/applehttps://github.com/swift-server 看到相种, 自 iOS 13 以來 蘋果新增了約 10+ Pure Swift Library , 10+ Open Source Swift Library, 以及針對(duì) 144 個(gè)公開 Framework威恼,根據(jù) Swift Style 重新設(shè)計(jì)了 57 個(gè) Framework 的API。

從以下數(shù)據(jù):

  1. 從 WWDC17 后 蘋果已經(jīng)不再使用 Objective-C 做 Sample Code 演示

  2. https://developer.apple.com/不再更新 Objective-C 相關(guān)的文檔

  3. WidgetKit 是 SwiftUI only寝并。

  4. App Clips 10M的包大小箫措, SwiftUI 是最合適的框架

  5. 開源社區(qū)逐步放棄 Objecive-C 如 Lottie。

可以判斷衬潦,Swift 是未來 Apple 平臺(tái)的唯一選擇斤蔓,越是有包袱的大廠 APP,從現(xiàn)在還不盡早儲(chǔ)備镀岛,在未來越會(huì)寸步難行弦牡。

我們需要做些什么?

? Swift我們已經(jīng)做了什么

  1. 一套支持 Swift 二進(jìn)制的研發(fā)環(huán)境

  2. 300+ 支持了混編的淘系 SDK哎媚。

  3. 手淘落地了 6 個(gè)模塊喇伯。

  4. 集團(tuán)新增了約 20個(gè) 支持 Swift 的APP。

  5. 10 多場(chǎng)技術(shù)培訓(xùn)拨与。

  6. 169+ 語雀知識(shí)沉淀稻据。

  7. 300+ 工程師的集團(tuán) Swift 官方組織。

  8. 2 個(gè) 技術(shù)創(chuàng)新產(chǎn)品

經(jīng)過去年橫向組織大家共同的努力,我們已經(jīng)已經(jīng)支持了橫向大基建捻悯。包括研發(fā)環(huán)境匆赃,工具支撐,沉淀了大量的文檔今缚,還有相關(guān)的技術(shù)課程算柳。

要朝什么方向去努力

目前集團(tuán)對(duì)于 Swift 的呼聲越來越高,我們大量的工程師希望的去使用 Swift 姓言。
目前首先要做的事情是依托 Swift 和 SPM 提升我們的開發(fā)體驗(yàn)瞬项,升級(jí)我們的中間件,使業(yè)務(wù)可以大量的用起來 Swift 何荚,提高我們的研發(fā)效率和代碼質(zhì)量囱淋。

  1. 升級(jí)基于 SPM 的新的包管理體系

  2. 升級(jí)老舊基礎(chǔ)庫(kù),打磨新一代基建餐塘。

  3. 引入新的 Swift 特有庫(kù) 賦能業(yè)務(wù)妥衣。

? SwiftUI雖然前文提到了 SwiftUI 的眾多優(yōu)點(diǎn),包括研發(fā)效率戒傻,體驗(yàn)的提高税手,但是在國(guó)內(nèi)的環(huán)境中 SwiftUI 也有它致命的弊端

  1. iOS 14 才可放心的使用。

  2. 只支持 Apple Platform需纳,這和國(guó)內(nèi)的要支持 Mobile Platform 從理念上沖突芦倒。

大型 APP 要解決的是如何部署到低版本操作系統(tǒng)上和安卓平臺(tái)上,畢竟很多公司還在支持 iOS 9 對(duì)于升級(jí)到最低支持 iOS 14 好像還需要一個(gè)世紀(jì)那么漫長(zhǎng)候齿,而且國(guó)內(nèi)的設(shè)備占比大頭還是以 Android 巨多 熙暴。

雖然可以看到 Swift 語言也在逐漸支持 Android 平臺(tái),但是也看到蘋果對(duì)于安卓平臺(tái)的 SwiftUI 并沒有太大興趣慌盯。

從體驗(yàn)上 Flutter 遠(yuǎn)不如 SwiftUI 這種親兒子效果好周霉, 但對(duì)于國(guó)內(nèi)跨端欲望旺盛的市場(chǎng)來說 SwiftUI 還是比不過 Flutter, 不過既然 SwiftUI DSL 層已經(jīng)基本固定亚皂,那么也有可能投入人力直接在低版本操作系統(tǒng)上實(shí)現(xiàn)一套自建的 SwiftUI 引擎俱箱,或者將 SwiftUI 引擎移植到安卓平臺(tái),比如對(duì)接 Flutter 或者直接對(duì)接 Android Native灭必。

比起 Flutter 引入雙端帶來的包大小增量和體驗(yàn)不一致的情況狞谱, SwiftUI 保留 iOS 平臺(tái)體驗(yàn),只侵入一端的選擇顯然要更好一點(diǎn)禁漓。

不過短期內(nèi)我們可以在 Clips 和 Widget 場(chǎng)景下開始使用 SwiftUI跟衅, 畢竟 SwiftUI 快速的開發(fā)效率對(duì)和較低的包大小占用非常適合這樣的場(chǎng)景,我們可以在業(yè)務(wù)場(chǎng)景中練兵儲(chǔ)備我們的 SwiftUI播歼,并積極在主 APP 中嘗試伶跷。


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子叭莫,更是在濱河造成了極大的恐慌蹈集,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雇初,死亡現(xiàn)場(chǎng)離奇詭異拢肆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)靖诗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門郭怪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人刊橘,你說我怎么就攤上這事移盆。” “怎么了伤为?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)据途。 經(jīng)常有香客問我绞愚,道長(zhǎng),這世上最難降的妖魔是什么颖医? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任位衩,我火速辦了婚禮,結(jié)果婚禮上熔萧,老公的妹妹穿的比我還像新娘糖驴。我一直安慰自己,他們只是感情好佛致,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布贮缕。 她就那樣靜靜地躺著,像睡著了一般俺榆。 火紅的嫁衣襯著肌膚如雪感昼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天罐脊,我揣著相機(jī)與錄音定嗓,去河邊找鬼。 笑死萍桌,一個(gè)胖子當(dāng)著我的面吹牛宵溅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播上炎,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼恃逻,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辛块,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤畔派,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后润绵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體线椰,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年尘盼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了憨愉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡卿捎,死狀恐怖配紫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情午阵,我是刑警寧澤躺孝,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站底桂,受9級(jí)特大地震影響植袍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜籽懦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一于个、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧暮顺,春花似錦厅篓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至惫恼,卻和暖如春乏苦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背尤筐。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工汇荐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盆繁。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓掀淘,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親油昂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子革娄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359