iOS 流暢度性能優(yōu)化胰伍、CPU、GPU酸休、離屏渲染

屏幕顯示圖像的原理

ios_screen_scan

首先從過(guò)去的 CRT 顯示器原理說(shuō)起骂租。CRT 的電子槍按照上面方式,從上到下一行行掃描雨席,掃描完成后顯示器就呈現(xiàn)一幀畫(huà)面菩咨,隨后電子槍回到初始位置繼續(xù)下一次掃描。為了把顯示器的顯示過(guò)程和系統(tǒng)的視頻控制器進(jìn)行同步陡厘,顯示器(或者其他硬件)會(huì)用硬件時(shí)鐘產(chǎn)生一系列的定時(shí)信號(hào)抽米。當(dāng)電子槍換到新的一行,準(zhǔn)備進(jìn)行掃描時(shí)糙置,顯示器會(huì)發(fā)出一個(gè)水平同步信號(hào)(horizonal synchronization)云茸,簡(jiǎn)稱 HSync;而當(dāng)一幀畫(huà)面繪制完成后谤饭,電子槍回復(fù)到原位标捺,準(zhǔn)備畫(huà)下一幀前,顯示器會(huì)發(fā)出一個(gè)垂直同步信號(hào)(vertical synchronization)揉抵,簡(jiǎn)稱 VSync亡容。顯示器通常以固定頻率進(jìn)行刷新,這個(gè)刷新率就是 VSync 信號(hào)產(chǎn)生的頻率冤今。盡管現(xiàn)在的設(shè)備大都是液晶顯示屏了闺兢,但原理仍然沒(méi)有變。

ios_screen_display

通常來(lái)說(shuō)戏罢,計(jì)算機(jī)系統(tǒng)中 CPU屋谭、GPU、顯示器是以上面這種方式協(xié)同工作的龟糕。CPU 計(jì)算好顯示內(nèi)容提交到 GPU桐磁,GPU 渲染完成后將渲染結(jié)果放入幀緩沖區(qū),隨后視頻控制器會(huì)按照 VSync 信號(hào)逐行讀取幀緩沖區(qū)的數(shù)據(jù)讲岁,經(jīng)過(guò)可能的數(shù)模轉(zhuǎn)換傳遞給顯示器顯示我擂。

在最簡(jiǎn)單的情況下衬以,幀緩沖區(qū)只有一個(gè),這時(shí)幀緩沖區(qū)的讀取和刷新都都會(huì)有比較大的效率問(wèn)題扶踊。為了解決效率問(wèn)題泄鹏,顯示系統(tǒng)通常會(huì)引入兩個(gè)緩沖區(qū)郎任,即雙緩沖機(jī)制秧耗。在這種情況下耘戚,GPU 會(huì)預(yù)先渲染好一幀放入一個(gè)緩沖區(qū)內(nèi)原环,讓視頻控制器讀取番枚,當(dāng)下一幀渲染好后穿肄,GPU 會(huì)直接把視頻控制器的指針指向第二個(gè)緩沖器咽扇。如此一來(lái)效率會(huì)有很大的提升出嘹。

雙緩沖雖然能解決效率問(wèn)題吼蚁,但會(huì)引入一個(gè)新的問(wèn)題讶凉。當(dāng)視頻控制器還未讀取完成時(shí)惜浅,即屏幕內(nèi)容剛顯示一半時(shí)瘫辩,GPU 將新的一幀內(nèi)容提交到幀緩沖區(qū)并把兩個(gè)緩沖區(qū)進(jìn)行交換后,視頻控制器就會(huì)把新的一幀數(shù)據(jù)的下半段顯示到屏幕上坛悉,造成畫(huà)面撕裂現(xiàn)象伐厌,如下圖:

ios_vsync_off

為了解決這個(gè)問(wèn)題,GPU 通常有一個(gè)機(jī)制叫做垂直同步(簡(jiǎn)寫(xiě)也是 V-Sync)裸影,當(dāng)開(kāi)啟垂直同步后挣轨,GPU 會(huì)等待顯示器的 VSync 信號(hào)發(fā)出后,才進(jìn)行新的一幀渲染和緩沖區(qū)更新轩猩。這樣能解決畫(huà)面撕裂現(xiàn)象卷扮,也增加了畫(huà)面流暢度,但需要消費(fèi)更多的計(jì)算資源均践,也會(huì)帶來(lái)部分延遲晤锹。

那么目前主流的移動(dòng)設(shè)備是什么情況呢?從網(wǎng)上查到的資料可以知道彤委,iOS 設(shè)備會(huì)始終使用雙緩存鞭铆,并開(kāi)啟垂直同步。而安卓設(shè)備直到 4.1 版本葫慎,Google 才開(kāi)始引入這種機(jī)制衔彻,目前安卓系統(tǒng)是三緩存+垂直同步。

卡頓產(chǎn)生的原因和解決方案
ios_frame_drop

在 VSync 信號(hào)到來(lái)后偷办,系統(tǒng)圖形服務(wù)會(huì)通過(guò) CADisplayLink 等機(jī)制通知 App艰额,App 主線程開(kāi)始在 CPU 中計(jì)算顯示內(nèi)容,比如視圖的創(chuàng)建椒涯、布局計(jì)算柄沮、圖片解碼、文本繪制等。隨后 CPU 會(huì)將計(jì)算好的內(nèi)容提交到 GPU 去祖搓,由 GPU 進(jìn)行變換狱意、合成、渲染拯欧。隨后 GPU 會(huì)把渲染結(jié)果提交到幀緩沖區(qū)去详囤,等待下一次 VSync 信號(hào)到來(lái)時(shí)顯示到屏幕上。由于垂直同步的機(jī)制镐作,如果在一個(gè) VSync 時(shí)間內(nèi)藏姐,CPU 或者 GPU 沒(méi)有完成內(nèi)容提交,則那一幀就會(huì)被丟棄该贾,等待下一次機(jī)會(huì)再顯示羔杨,而這時(shí)顯示屏?xí)A糁暗膬?nèi)容不變。這就是界面卡頓的原因杨蛋。

從上面的圖中可以看到兜材,CPU 和 GPU 不論哪個(gè)阻礙了顯示流程,都會(huì)造成掉幀現(xiàn)象逞力。所以開(kāi)發(fā)時(shí)曙寡,也需要分別對(duì) CPU 和 GPU 壓力進(jìn)行評(píng)估和優(yōu)化。

CPU 資源消耗原因和解決方案
對(duì)象創(chuàng)建
對(duì)象的創(chuàng)建會(huì)分配內(nèi)存掏击、調(diào)整屬性卵皂、甚至還有讀取文件等操作,比較消耗 CPU 資源砚亭。盡量用輕量的對(duì)象代替重量的對(duì)象灯变,可以對(duì)性能有所優(yōu)化。比如 CALayer 比 UIView 要輕量許多捅膘,那么不需要響應(yīng)觸摸事件的控件添祸,用 CALayer 顯示會(huì)更加合適。如果對(duì)象不涉及 UI 操作寻仗,則盡量放到后臺(tái)線程去創(chuàng)建刃泌,但可惜的是包含有 CALayer 的控件,都只能在主線程創(chuàng)建和操作署尤。通過(guò) Storyboard 創(chuàng)建視圖對(duì)象時(shí)耙替,其資源消耗會(huì)比直接通過(guò)代碼創(chuàng)建對(duì)象要大非常多,在性能敏感的界面里曹体,Storyboard 并不是一個(gè)好的技術(shù)選擇俗扇。
盡量推遲對(duì)象創(chuàng)建的時(shí)間,并把對(duì)象的創(chuàng)建分散到多個(gè)任務(wù)中去箕别。盡管這實(shí)現(xiàn)起來(lái)比較麻煩铜幽,并且?guī)?lái)的優(yōu)勢(shì)并不多滞谢,但如果有能力做,還是要盡量嘗試一下除抛。如果對(duì)象可以復(fù)用狮杨,并且復(fù)用的代價(jià)比釋放、創(chuàng)建新對(duì)象要小到忽,那么這類(lèi)對(duì)象應(yīng)當(dāng)盡量放到一個(gè)緩存池里復(fù)用橄教。
對(duì)象調(diào)整
對(duì)象的調(diào)整也經(jīng)常是消耗 CPU 資源的地方。這里特別說(shuō)一下 CALayer:CALayer 內(nèi)部并沒(méi)有屬性绘趋,當(dāng)調(diào)用屬性方法時(shí)颤陶,它內(nèi)部是通過(guò)運(yùn)行時(shí) resolveInstanceMethod 為對(duì)象臨時(shí)添加一個(gè)方法颗管,并把對(duì)應(yīng)屬性值保存到內(nèi)部的一個(gè) Dictionary 里陷遮,同時(shí)還會(huì)通知 delegate、創(chuàng)建動(dòng)畫(huà)等等垦江,非常消耗資源帽馋。UIView 的關(guān)于顯示相關(guān)的屬性(比如 frame/bounds/transform)等實(shí)際上都是 CALayer 屬性映射來(lái)的,所以對(duì) UIView 的這些屬性進(jìn)行調(diào)整時(shí)比吭,消耗的資源要遠(yuǎn)大于一般的屬性绽族。對(duì)此你在應(yīng)用中,應(yīng)該盡量減少不必要的屬性修改衩藤。
當(dāng)視圖層次調(diào)整時(shí)吧慢,UIView、CALayer 之間會(huì)出現(xiàn)很多方法調(diào)用與通知赏表,所以在優(yōu)化性能時(shí)检诗,應(yīng)該盡量避免調(diào)整視圖層次、添加和移除視圖瓢剿。
對(duì)象銷(xiāo)毀
對(duì)象的銷(xiāo)毀雖然消耗資源不多逢慌,但累積起來(lái)也是不容忽視的。通常當(dāng)容器類(lèi)持有大量對(duì)象時(shí)间狂,其銷(xiāo)毀時(shí)的資源消耗就非常明顯攻泼。同樣的,如果對(duì)象可以放到后臺(tái)線程去釋放鉴象,那就挪到后臺(tái)線程去忙菠。這里有個(gè)小 Tip:把對(duì)象捕獲到 block 中,然后扔到后臺(tái)隊(duì)列去隨便發(fā)送個(gè)消息以避免編譯器警告纺弊,就可以讓對(duì)象在后臺(tái)線程銷(xiāo)毀了牛欢。

NSArray *tmp = self.array;
self.array = nil;
dispatch_async(queue, ^{
    [tmp class];
});

** 布局計(jì)算**
視圖布局的計(jì)算是 App 中最為常見(jiàn)的消耗 CPU 資源的地方。如果能在后臺(tái)線程提前計(jì)算好視圖布局俭尖、并且對(duì)視圖布局進(jìn)行緩存氢惋,那么這個(gè)地方基本就不會(huì)產(chǎn)生性能問(wèn)題了洞翩。
不論通過(guò)何種技術(shù)對(duì)視圖進(jìn)行布局,其最終都會(huì)落到對(duì) UIView.frame/bounds/center 等屬性的調(diào)整上焰望。上面也說(shuō)過(guò)骚亿,對(duì)這些屬性的調(diào)整非常消耗資源,所以盡量提前計(jì)算好布局熊赖,在需要時(shí)一次性調(diào)整好對(duì)應(yīng)屬性来屠,而不要多次、頻繁的計(jì)算和調(diào)整這些屬性震鹉。
Autolayout
Autolayout 是蘋(píng)果本身提倡的技術(shù),在大部分情況下也能很好的提升開(kāi)發(fā)效率传趾,但是 Autolayout 對(duì)于復(fù)雜視圖來(lái)說(shuō)常常會(huì)產(chǎn)生嚴(yán)重的性能問(wèn)題。隨著視圖數(shù)量的增長(zhǎng)磕仅,Autolayout 帶來(lái)的 CPU 消耗會(huì)呈指數(shù)級(jí)上升。具體數(shù)據(jù)可以看這個(gè)文章:http://pilky.me/36/簸呈。 如果你不想手動(dòng)調(diào)整 frame 等屬性榕订,你可以用一些工具方法替代(比如常見(jiàn)的 left/right/top/bottom/width/height 快捷屬性)蜕便,或者使用 ComponentKit、AsyncDisplayKit 等框架轿腺。
文本計(jì)算
如果一個(gè)界面中包含大量文本(比如微博微信朋友圈等)两嘴,文本的寬高計(jì)算會(huì)占用很大一部分資源,并且不可避免吃溅。如果你對(duì)文本顯示沒(méi)有特殊要求,可以參考下 UILabel 內(nèi)部的實(shí)現(xiàn)方式:用 [NSAttributedString boundingRectWithSize:options:context:] 來(lái)計(jì)算文本寬高螺垢,用 -[NSAttributedString drawWithRect:options:context:] 來(lái)繪制文本赖歌。盡管這兩個(gè)方法性能不錯(cuò),但仍舊需要放到后臺(tái)線程進(jìn)行以避免阻塞主線程庐冯。
如果你用 CoreText 繪制文本,那就可以先生成 CoreText 排版對(duì)象返劲,然后自己計(jì)算了,并且 CoreText 對(duì)象還能保留以供稍后繪制使用孵延。
文本渲染
屏幕上能看到的所有文本內(nèi)容控件亲配,包括 UIWebView,在底層都是通過(guò) CoreText 排版吼虎、繪制為 Bitmap 顯示的。常見(jiàn)的文本控件 (UILabel玷犹、UITextView 等)官辈,其排版和繪制都是在主線程進(jìn)行的,當(dāng)顯示大量文本時(shí),CPU 的壓力會(huì)非常大愿伴。對(duì)此解決方案只有一個(gè)肺魁,那就是自定義文本控件隔节,用 TextKit 或最底層的 CoreText 對(duì)文本異步繪制怎诫。盡管這實(shí)現(xiàn)起來(lái)非常麻煩,但其帶來(lái)的優(yōu)勢(shì)也非常大幻妓,CoreText 對(duì)象創(chuàng)建好后肉津,能直接獲取文本的寬高等信息,避免了多次計(jì)算(調(diào)整 UILabel 大小時(shí)算一遍妹沙、UILabel 繪制時(shí)內(nèi)部再算一遍)距糖;CoreText 對(duì)象占用內(nèi)存較少牵寺,可以緩存下來(lái)以備稍后多次渲染恩脂。
圖片的解碼
當(dāng)你用 UIImage 或 CGImageSource 的那幾個(gè)方法創(chuàng)建圖片時(shí),圖片數(shù)據(jù)并不會(huì)立刻解碼杏节。圖片設(shè)置到 UIImageView 或者 CALayer.contents 中去典阵,并且 CALayer 被提交到 GPU 前,CGImage 中的數(shù)據(jù)才會(huì)得到解碼嫉鲸。這一步是發(fā)生在主線程的歹啼,并且不可避免狸眼。如果想要繞開(kāi)這個(gè)機(jī)制,常見(jiàn)的做法是在后臺(tái)線程先把圖片繪制到 CGBitmapContext 中拓萌,然后從 Bitmap 直接創(chuàng)建圖片微王。目前常見(jiàn)的網(wǎng)絡(luò)圖片庫(kù)都自帶這個(gè)功能。
** 圖像的繪制**
圖像的繪制通常是指用那些以 CG 開(kāi)頭的方法把圖像繪制到畫(huà)布中钧大,然后從畫(huà)布創(chuàng)建圖片并顯示這樣一個(gè)過(guò)程罩旋。這個(gè)最常見(jiàn)的地方就是 [UIView drawRect:] 里面了。由于 CoreGraphic 方法通常都是線程安全的劣挫,所以圖像的繪制可以很容易的放到后臺(tái)線程進(jìn)行东帅。一個(gè)簡(jiǎn)單異步繪制的過(guò)程大致如下(實(shí)際情況會(huì)比這個(gè)復(fù)雜得多,但原理基本一致):

- (void)display {
    dispatch_async(backgroundQueue, ^{
        CGContextRef ctx = CGBitmapContextCreate(...);
        // draw in context...
        CGImageRef img = CGBitmapContextCreateImage(ctx);
        CFRelease(ctx);
        dispatch_async(mainQueue, ^{
            layer.contents = img;
        });
    });
}

** GPU 資源消耗原因和解決方案**
相對(duì)于 CPU 來(lái)說(shuō)帐我,GPU 能干的事情比較單一:接收提交的紋理(Texture)和頂點(diǎn)描述(三角形),應(yīng)用變換(transform)谣光、混合并渲染芬为,然后輸出到屏幕上媚朦。通常你所能看到的內(nèi)容,主要也就是紋理(圖片)和形狀(三角模擬的矢量圖形)兩類(lèi)询张。
紋理的渲染
所有的 Bitmap份氧,包括圖片、文本蜗帜、柵格化的內(nèi)容钮糖,最終都要由內(nèi)存提交到顯存,綁定為 GPU Texture。不論是提交到顯存的過(guò)程酪我,還是 GPU 調(diào)整和渲染 Texture 的過(guò)程都哭,都要消耗不少 GPU 資源。當(dāng)在較短時(shí)間顯示大量圖片時(shí)(比如 TableView 存在非常多的圖片并且快速滑動(dòng)時(shí))纱新,CPU 占用率很低穆趴,GPU 占用非常高,界面仍然會(huì)掉幀簿废。避免這種情況的方法只能是盡量減少在短時(shí)間內(nèi)大量圖片的顯示,盡可能將多張圖片合成為一張進(jìn)行顯示歪赢。
當(dāng)圖片過(guò)大单料,超過(guò) GPU 的最大紋理尺寸時(shí),圖片需要先由 CPU 進(jìn)行預(yù)處理白对,這對(duì) CPU 和 GPU 都會(huì)帶來(lái)額外的資源消耗藏斩。目前來(lái)說(shuō),iPhone 4S 以上機(jī)型媳拴,紋理尺寸上限都是 4096x4096兆览,更詳細(xì)的資料可以看這里:iosres.com抬探。所以,盡量不要讓圖片和視圖的大小超過(guò)這個(gè)值线梗。
視圖的混合 (Composing)
當(dāng)多個(gè)視圖(或者說(shuō) CALayer)重疊在一起顯示時(shí)怠益,GPU 會(huì)首先把他們混合到一起。如果視圖結(jié)構(gòu)過(guò)于復(fù)雜烤咧,混合的過(guò)程也會(huì)消耗很多 GPU 資源抢呆。為了減輕這種情況的 GPU 消耗,應(yīng)用應(yīng)當(dāng)盡量減少視圖數(shù)量和層次昌阿,并在不透明的視圖里標(biāo)明 opaque 屬性以避免無(wú)用的 Alpha 通道合成。當(dāng)然好啰,這也可以用上面的方法儿奶,把多個(gè)視圖預(yù)先渲染為一張圖片來(lái)顯示闯捎。
圖形的生成。
CALayer 的 border秉版、圓角茬祷、陰影、遮罩(mask)秸妥,CASharpLayer 的矢量圖形顯示沃粗,通常會(huì)觸發(fā)離屏渲染(offscreen rendering)最盅,而離屏渲染通常發(fā)生在 GPU 中。當(dāng)一個(gè)列表視圖中出現(xiàn)大量圓角的 CALayer涡贱,并且快速滑動(dòng)時(shí)问词,可以觀察到 GPU 資源已經(jīng)占滿,而 CPU 資源消耗很少。這時(shí)界面仍然能正巢菽拢滑動(dòng)悲柱,但平均幀數(shù)會(huì)降到很低。為了避免這種情況嘿般,可以嘗試開(kāi)啟 CALayer.shouldRasterize 屬性,但這會(huì)把原本離屏渲染的操作轉(zhuǎn)嫁到 CPU 上去逼庞。對(duì)于只需要圓角的某些場(chǎng)合瞻赶,也可以用一張已經(jīng)繪制好的圓角圖片覆蓋到原本視圖上面來(lái)模擬相同的視覺(jué)效果。最徹底的解決辦法璧南,就是把需要顯示的圖形在后臺(tái)線程繪制為圖片司倚,避免使用圓角篓像、陰影、遮罩等屬性拍柒。

預(yù)排版

當(dāng)獲取到 API JSON 數(shù)據(jù)后屈暗,我會(huì)把每條 Cell 需要的數(shù)據(jù)都在后臺(tái)線程計(jì)算并封裝為一個(gè)布局對(duì)象 CellLayout。CellLayout 包含所有文本的 CoreText 排版結(jié)果养叛、Cell 內(nèi)部每個(gè)控件的高度弃甥、Cell 的整體高度。每個(gè) CellLayout 的內(nèi)存占用并不多阔墩,所以當(dāng)生成后瓶珊,可以全部緩存到內(nèi)存,以供稍后使用忘苛。這樣,TableView 在請(qǐng)求各個(gè)高度函數(shù)時(shí)召川,不會(huì)消耗任何多余計(jì)算量胸遇;當(dāng)把 CellLayout 設(shè)置到 Cell 內(nèi)部時(shí)狐榔,Cell 內(nèi)部也不用再計(jì)算布局了。

對(duì)于通常的 TableView 來(lái)說(shuō)收捣,提前在后臺(tái)計(jì)算好布局結(jié)果是非常重要的一個(gè)性能優(yōu)化點(diǎn)庵楷。為了達(dá)到最高性能尽纽,你可能需要犧牲一些開(kāi)發(fā)速度,不要用 Autolayout 等技術(shù)春锋,少用 UILabel 等文本控件差凹。但如果你對(duì)性能的要求并不那么高危尿,可以嘗試用 TableView 的預(yù)估高度的功能,并把每個(gè) Cell 高度緩存下來(lái)肺孤。這里有個(gè)來(lái)自百度知道團(tuán)隊(duì)的開(kāi)源項(xiàng)目可以很方便的幫你實(shí)現(xiàn)這一點(diǎn):FDTemplateLayoutCellhttp://blog.sunnyxx.com/2015/05/17/cell-height-calculation/济欢。
http://blog.sunnyxx.com

非本人原創(chuàng)法褥,只為學(xué)習(xí)和交流筆記。
附上原文地址:http://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市酱鸭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌烁登,老刑警劉巖蔚舀,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赌躺,死亡現(xiàn)場(chǎng)離奇詭異礼患,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)悄泥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)弹囚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)领曼,“玉大人,你說(shuō)我怎么就攤上這事宋舷∽r穑” “怎么了幻碱?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵褥傍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蹦狂,道長(zhǎng),這世上最難降的妖魔是什么窜骄? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任邻遏,我火速辦了婚禮虐骑,結(jié)果婚禮上廷没,老公的妹妹穿的比我還像新娘。我一直安慰自己济似,他們只是感情好盏缤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布唉铜。 她就那樣靜靜地躺著潭流,像睡著了一般。 火紅的嫁衣襯著肌膚如雪灰嫉。 梳的紋絲不亂的頭發(fā)上讼撒,一...
    開(kāi)封第一講書(shū)人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音根盒,去河邊找鬼炎滞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛钠导,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播责掏,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼证芭!你這毒婦竟也來(lái)了担映?” 一聲冷哼從身側(cè)響起废士,我...
    開(kāi)封第一講書(shū)人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝇完,沒(méi)想到半個(gè)月后官硝,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡短蜕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年氢架,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片朋魔。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岖研,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出孙援,到底是詐尸還是另有隱情,我是刑警寧澤扇雕,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布拓售,位于F島的核電站,受9級(jí)特大地震影響镶奉,放射性物質(zhì)發(fā)生泄漏础淤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一腮鞍、第九天 我趴在偏房一處隱蔽的房頂上張望值骇。 院中可真熱鬧,春花似錦移国、人聲如沸吱瘩。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)使碾。三九已至蜜徽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間票摇,已是汗流浹背拘鞋。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留矢门,地道東北人盆色。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像祟剔,于是被迫代替她去往敵國(guó)和親隔躲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

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