iOS核心動畫高級技巧--(十四)圖像IO

在第13章“高效繪圖”中游岳,我們研究了和Core Graphics繪圖相關(guān)的性能問題杠娱,以及如何修復(fù)乏奥。和繪圖性能相關(guān)緊密相關(guān)的是圖像性能谅畅。在這一章中登渣,我們將研究如何 優(yōu)化從閃存驅(qū)動器或者網(wǎng)絡(luò)中加載和顯示圖片。

加載和潛伏

繪圖實際消耗的時間通常并不是影響性能的因素毡泻。圖片消耗很大一部分內(nèi)存胜茧,而且不太可能把需要顯示的圖片都保留在內(nèi)存中,所以需要在應(yīng)用運(yùn)行的時候周期性地加載和卸載圖片仇味。

圖片文件加載的速度被CPUIO(輸入/輸出)同時影響呻顽。iOS設(shè)備中的閃存已經(jīng) 比傳統(tǒng)硬盤快很多了,但仍然比RAM慢將近200倍左右丹墨,這就需要很小心地管理加載廊遍,來避免延遲。

只要有可能贩挣,試著在程序生命周期不易察覺的時候來加載圖片喉前,例如啟動英染,或者在屏幕切換的過程中。按下按鈕和按鈕響應(yīng)事件之間最大的延遲大概是200ms被饿,這 比動畫每一幀切換的16ms小得多四康。你可以在程序首次啟動的時候加載圖片,但是如果20秒內(nèi)無法啟動程序的話狭握,iOS檢測計時器就會終止你的應(yīng)用(而且如果啟動 大于2闪金,3秒的話用戶就會抱怨了)。

有些時候论颅,提前加載所有的東西并不明智哎垦。比如說包含上千張圖片的圖片傳送帶:用戶希望能夠能夠平滑快速翻動圖片,所以就不可能提前預(yù)加載所有圖片;那樣會消耗太多的時間和內(nèi)存恃疯。

有時候圖片也需要從遠(yuǎn)程網(wǎng)絡(luò)連接中下載漏设,這將會比從磁盤加載要消耗更多的時間,甚至可能由于連接問題而加載失敗(在幾秒鐘嘗試之后)今妄。你不能夠在主線程中加載網(wǎng)絡(luò)造成等待郑口,所以需要后臺程。

線程加載

第12章“性能調(diào)優(yōu)”我們的聯(lián)系人列表例子中盾鳞,圖片都非常小犬性,所以可以在主線 程同步加載。但是對于大圖來說腾仅,這樣做就不太合適了乒裆,因為加載會消耗很長時間,造成滑動的不流暢推励『姿#滑動動畫會在主線程的run loop中更新,所以會有更多運(yùn) 行在渲染服務(wù)進(jìn)程中CPU相關(guān)的性能問題验辞。

GCD和 NSOperationQueue

GCD(Grand Central Dispatch)NSOperationQueue很類似稿黄,都給我們提供 了隊列閉包塊來在線程中按一定順序來執(zhí)行。 NSOperationQueue 有一個 Objecive-C接口(而不是使用GCD的全局C函數(shù))受神,同樣在操作優(yōu)先級和依賴關(guān)系 上提供了很好的粒度控制抛猖,但是需要更多地設(shè)置代碼格侯。

延遲解壓

一旦圖片文件被加載就必須要進(jìn)行解碼鼻听,解碼過程是一個相當(dāng)復(fù)雜的任務(wù),需要消耗非常長的時間联四。解碼后的圖片將同樣使用相當(dāng)大的內(nèi)存撑碴。

用于加載的CPU時間相對于解碼來說根據(jù)圖片格式而不同。對于PNG圖片來說朝墩, 加載會比JPEG更長醉拓,因為文件可能更大,但是解碼會相對較快,而且Xcode會把 PNG圖片進(jìn)行解碼優(yōu)化之后引入工程亿卤。JPEG圖片更小愤兵,加載更快,但是解壓的步 驟要消耗更長的時間排吴,因為JPEG解壓算法比基于zipPNG算法更加復(fù)雜秆乳。

當(dāng)加載圖片的時候,iOS通常會延遲解壓圖片的時間钻哩,直到加載到內(nèi)存之后屹堰。這就會在準(zhǔn)備繪制圖片的時候影響性能,因為需要在繪制之前進(jìn)行解壓(通常是消耗 時間的問題所在)街氢。

最簡單的方法就是使用UIImage+ imageNamed: 方法避免延時加載扯键。不像+ +imageWithContentsOfFile: (和其他別的 UIImage 加載方法),這個方法會在加載圖片之后立刻進(jìn)行解壓(就和本章之前我們談到的好處一樣)珊肃。問題在于 +imageNamed: 只對從應(yīng)用資源束中的圖片有效荣刑,所以對用戶生成的圖片內(nèi)容 或者是下載的圖片就沒法使用了。

另一種立刻加載圖片的方法就是把它設(shè)置成圖層內(nèi)容伦乔,或者是UIImageViewimage屬性嘶摊。不幸的是,這又需要在主線程執(zhí)行评矩,所以不會 對性能有所提升叶堆。

第三種方式就是繞過 UIKit,像下面這樣使用ImageIO框架:

這樣就可以使用 kCGImageSourceShouldCache來創(chuàng)建圖片斥杜,強(qiáng)制圖片立刻解 壓虱颗,然后在圖片的生命周期保留解壓后的版本。

最后一種方式就是使用UIKit加載圖片蔗喂,但是立刻會知道 CGContext中去忘渔。圖片必須要在繪制之前解壓,所以就強(qiáng)制了解壓的及時性缰儿。這樣的好處在于繪制圖片可以在后臺線程(例如加載本身)執(zhí)行畦粮,而不會阻塞UI

有兩種方式可以為強(qiáng)制解壓提前渲染圖片:

  • 將圖片的一個像素繪制成一個像素大小的 CGContext乖阵。這樣仍然會解壓整張圖片宣赔,但是繪制本身并沒有消耗任何時間。這樣的好處在于加載的圖片并不會 在特定的設(shè)備上為繪制做優(yōu)化瞪浸,所以可以在任何時間點繪制出來儒将。同樣iOS也 就可以丟棄解壓后的圖片來節(jié)省內(nèi)存了。
  • 將整張圖片繪制到 CGContext中对蒲,丟棄原始的圖片钩蚊,并且用一個從上下文內(nèi) 容中新的圖片來代替贡翘。這樣比繪制單一像素那樣需要更加復(fù)雜的計算,但是因 此產(chǎn)生的圖片將會為繪制做優(yōu)化砰逻,而且由于原始壓縮圖片被拋棄了鸣驱,iOS就不能夠隨時丟棄任何解壓后的圖片來節(jié)省內(nèi)存了。

需要注意的是蘋果特別推薦了不要使用這些詭計來繞過標(biāo)準(zhǔn)圖片解壓邏輯(所以也是他們選擇用默認(rèn)處理方式的原因)蝠咆,但是如果你使用很多大圖來構(gòu)建應(yīng)用丐巫,那如果想提升性能,就只能和系統(tǒng)博弈了勺美。

如果不使用+imageNamed:递胧,那么把整張圖片繪制到 CGContext 可能是最佳的方式了。盡管你可能認(rèn)為多余的繪制相較別的解壓技術(shù)而言性能不是很高赡茸,但是 新創(chuàng)建的圖片(在特定的設(shè)備上做過優(yōu)化)可能比原始圖片繪制的更快缎脾。

同樣,如果想顯示圖片到比原始尺寸小的容器中占卧,那么一次性在后臺線程重新繪制到正確的尺寸會比每次顯示的時候都做縮放會更有效(盡管在這個例子中我們加
載的圖片呈現(xiàn)正確的尺寸遗菠,所以不需要多余的優(yōu)化)。

CATiledLayer

第6章“專用圖層”中的例子所示华蜒,CATiledLayer 可以用來異步加載和顯示大型圖片辙纬,而不阻塞用戶輸入。但是我們同樣可以使用 CATiledLayerUICollectionView中為每個表格創(chuàng)建分離
CATiledLayer 實例加載傳動器圖片叭喜,每個表格僅使用一個圖層贺拣。

這樣使用 CATiledLayer有幾個潛在的弊端:

  • CATiledLayer的隊列和緩存算法沒有暴露出來,所以我們只能祈禱它能匹配我們的需求
  • CATiledLayer 需要我們每次重繪圖片到 CGContext 中捂蕴,即使它已經(jīng)解壓縮譬涡,而且和我們單元格尺寸一樣(因此可以直接用作圖層內(nèi)容,而不需要重 繪)啥辨。

我們來看看這些弊端有沒有造成不同涡匀。

需要解釋幾點:

  • CATiledLayertileSize 屬性單位是像素,而不是點溉知,所以為了保證瓦片和表格尺寸一致陨瘩,需要乘以屏幕比例因子。

  • - drawLayer: inContext: 方法中级乍,我們需要知道圖層屬于哪一個 indexPath 以加載正確的圖片舌劳。這里我們利用了 CALayerKVC來存儲和檢索任意的值,將圖層和索引打標(biāo)簽卡者。

結(jié)果 CATiledLayer 工作的很好蒿囤,性能問題解決了,而且和用GCD實現(xiàn)的代碼 量差不多崇决。僅有一個問題在于圖片加載到屏幕上后有一個明顯的淡入材诽。

我們可以調(diào)整CATiledLayerfadeDuration屬性來調(diào)整淡入的速度,或者直接將整個漸變移除恒傻,但是這并沒有根本性地去除問題:在圖片加載到準(zhǔn)備繪制的 時候總會有一個延遲脸侥,這將會導(dǎo)致滑動時候新圖片的跳入。這并不是 CATiledLayer的問題盈厘,使用GCD的版本也有這個問題睁枕。

即使使用上述我們討論的所有加載圖片和緩存的技術(shù),有時候仍然會發(fā)現(xiàn)實時加載大圖還是有問題沸手。就和13章中提到的那樣外遇,iPad上一整個視網(wǎng)膜屏圖片分辨率達(dá) 到了2048x1536,而且會消耗12MBRAM(未壓縮)契吉。第三代iPad的硬件并不能 支持1/60秒的幀率加載跳仿,解壓和顯示這種圖片。即使用后臺線程加載來避免動畫卡頓捐晶,仍然解決不了問題菲语。

我們可以在加載的同時顯示一個占位圖片,但這并沒有根本解決問題惑灵,我們可以做到更好山上。

分辨率交換

視網(wǎng)膜分辨率(根據(jù)蘋果市場定義)代表了人的肉眼在正常視角距離能夠分辨的最小像素尺寸。但是這只能應(yīng)用于靜態(tài)像素英支。當(dāng)觀察一個移動圖片時佩憾,你的眼睛就會對細(xì)節(jié)不敏感,于是一個低分辨率的圖片和視網(wǎng)膜質(zhì)量的圖片沒什么區(qū)別了干花。

如果需要快速加載和顯示移動大圖鸯屿,簡單的辦法就是欺騙人眼,在移動傳送器的 時候顯示一個小圖(或者低分辨率)把敢,然后當(dāng)停止的時候再換成大圖寄摆。這意味著我 們需要對每張圖片存儲兩份不同分辨率的副本,但是幸運(yùn)的是修赞,由于需要同時支持 Retina非Retina設(shè)備婶恼,本來這就是普遍要做到的。

如果從遠(yuǎn)程源或者用戶的相冊加載沒有可用的低分辨率版本圖片柏副,那就可以動態(tài) 將大圖繪制到較小的 CGContext勾邦,然后存儲到某處以備復(fù)用。

為了做到圖片交換割择,我們需要利用 UIScrollView的一些實
現(xiàn)UIScrollViewDelegate 協(xié)議的委托方法(和其他類似于UITableViewUICollectionView 基于滾動視圖的控件一樣):

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset NS_AVAILABLE_IOS(5_0);

你可以使用這幾個方法來檢測傳送器是否停止?jié)L動眷篇,然后加載高分辨率的圖片。只要高分辨率圖片和低分辨率圖片尺寸顏色保持一致荔泳,你會很難察覺到替換的過程(確保在同一臺機(jī)器使用相同的圖像程序或者腳本生成這些圖片)蕉饼。

緩存

如果有很多張圖片要顯示虐杯,最好不要提前把所有都加載進(jìn)來,而是應(yīng)該當(dāng)移出屏幕之后立刻銷毀昧港。通過選擇性的緩存擎椰,你就可以避免來回滾動時圖片重復(fù)性的加載了。

緩存其實很簡單:就是存儲昂貴計算后的結(jié)果(或者是從閃存或者網(wǎng)絡(luò)加載的文 件)在內(nèi)存中创肥,以便后續(xù)使用达舒,這樣訪問起來很快。問題在于緩存本質(zhì)上是一個權(quán) 衡過程 - 為了提升性能而消耗了內(nèi)存叹侄,但是由于內(nèi)存是一個非常寶貴的資源巩搏,所以 不能把所有東西都做緩存。

何時將何物做緩存(做多久)并不總是很明顯趾代。幸運(yùn)的是贯底,大多情況下,iOS都 為我們做好了圖片的緩存稽坤。

+imageNamed: 方法

之前我們提到使用[UIImage imageName:]加載圖片有個好處在于可以立刻解 壓圖片而不用等到繪制的時候丈甸。但是[UIImage imageName:] 方法有另一個非常 顯著的好處:它在內(nèi)存中自動緩存了解壓后的圖片,即使你自己沒有保留對它的任何引用尿褪。

對于iOS應(yīng)用那些主要的圖片(例如圖標(biāo)睦擂,按鈕和背景圖片),使用[UIImage imageNamed:]加載圖片是最簡單最有效的方式杖玲。在nib文件中引用的圖片同樣也是這個機(jī)制顿仇,所以你很多時候都在隱式的使用它。

但是[UIImage imageNamed:] 并不適用任何情況摆马。它為用戶界面做了優(yōu)化臼闻,但是并不是對應(yīng)用程序需要顯示的所有類型的圖片都適用。有些時候你還是要實現(xiàn)自 己的緩存機(jī)制囤采,原因如下:

  • [UIImage imageNamed:] 方法僅僅適用于在應(yīng)用程序資源束目錄下的圖片述呐, 但是大多數(shù)應(yīng)用的許多圖片都要從網(wǎng)絡(luò)或者是用戶的相機(jī)中獲取,所以[UIImage imageNamed:] 就沒法用了蕉毯。

  • [UIImage imageNamed:]緩存用來存儲應(yīng)用界面的圖片(按鈕乓搬,背景等 等)。如果對照片這種大圖也用這種緩存代虾,那么iOS系統(tǒng)就很可能會移除這些圖片來節(jié)省內(nèi)存进肯。那么在切換頁面時性能就會下降,因為這些圖片都需要重新加載棉磨。對傳送器的圖片使用一個單獨的緩存機(jī)制就可以把它和應(yīng)用圖片的生命周期解耦江掩。

  • [UIImage imageNamed:]緩存機(jī)制并不是公開的,所以你不能很好地控制 它。例如环形,你沒法做到檢測圖片是否在加載之前就做了緩存策泣,不能夠設(shè)置緩存 大小,當(dāng)圖片沒用的時候也不能把它從緩存中移除斟赚。

自定義緩存

構(gòu)建一個所謂的緩存系統(tǒng)非常困難着降。菲爾 卡爾頓曾經(jīng)說過:“在計算機(jī)科學(xué)中只 有兩件難事:緩存和命名”差油。
如果要寫自己的圖片緩存的話拗军,那該如何實現(xiàn)呢?讓我們來看看要涉及哪些方面:

  • 選擇一個合適的緩存鍵 - 緩存鍵用來做圖片的唯一標(biāo)識。如果實時創(chuàng)建圖片蓄喇, 通常不太好生成一個字符串來區(qū)分別的圖片发侵。在我們的圖片傳送帶例子中就很 簡單,我們可以用圖片的文件名或者表格索引妆偏。

  • 提前緩存 - 如果生成和加載數(shù)據(jù)的代價很大刃鳄,你可能想當(dāng)?shù)谝淮涡枰玫降臅r 候再去加載和緩存。提前加載的邏輯是應(yīng)用內(nèi)在就有的钱骂,但是在我們的例子 中叔锐,這也非常好實現(xiàn),因為對于一個給定的位置和滾動方向见秽,我們就可以精確 地判斷出哪一張圖片將會出現(xiàn)愉烙。

  • 緩存失效 - 如果圖片文件發(fā)生了變化,怎樣才能通知到緩存更新呢?這是個非 常困難的問題(就像菲爾 卡爾頓提到的)解取,但是幸運(yùn)的是當(dāng)從程序資源加載靜 態(tài)圖片的時候并不需要考慮這些步责。對用戶提供的圖片來說(可能會被修改或者 覆蓋),一個比較好的方式就是當(dāng)圖片緩存的時候打上一個時間戳以便當(dāng)文件 更新的時候作比較禀苦。

  • 緩存回收 - 當(dāng)內(nèi)存不夠的時候蔓肯,如何判斷哪些緩存需要清空呢?這就需要到你 寫一個合適的算法了。幸運(yùn)的是振乏,對緩存回收的問題蔗包,蘋果提供了一個叫做NSCache通用的解決方案

NSCache

NSCacheNSDictionary 類似。你可以通過- setObject:forKey:- object:forKey:方法分別來插入分別來插入慧邮,檢索调限。和字典不同的是,NSCache 在系統(tǒng)低內(nèi)存的時候自動丟棄存儲的對象赋咽。

NSCache用來判斷何時丟棄對象的算法并沒有在文檔中給出旧噪,但是你可以使用- setCountLimit : 方法設(shè)置緩存大小,以及 -setObject:forKey:cost:來對每個存儲的對象指定消耗的值來提供一些暗示脓匿。

指定消耗數(shù)值可以用來指定相對的重建成本淘钟。如果對大圖指定一個大的消耗值, 那么緩存就知道這些物體的存儲更加昂貴陪毡,于是當(dāng)有大的性能問題的時候才會丟棄 這些物體米母。你也可以用- setTotalCostLimit:方法來指定全體緩存的尺寸勾扭。

NSCache是一個普遍的緩存解決方案,我們創(chuàng)建一個比傳送器案例更好的自定 義的緩存類铁瞒。(例如妙色,我們可以基于不同的緩存圖片索引和當(dāng)前中間索引來判斷哪些圖片需要首先被釋放)。但是 NSCache對我們當(dāng)前的緩存需求來說已經(jīng)足夠 了;沒必要過早做優(yōu)化慧耍。

文件格式

圖片加載性能取決于加載大圖的時間和解壓小圖時間的權(quán)衡身辨。很多蘋果的文檔都 說PNGiOS所有圖片加載的最好格式。但這是極度誤導(dǎo)的過時信息了芍碧。

PNG圖片使用的無損壓縮算法可以比使用JPEG的圖片做到更快地解壓煌珊,但是由 于閃存訪問的原因,這些加載的時間并沒有什么區(qū)別泌豆。

相對于不友好的PNG圖片定庵,相同像素的JPEG圖片總是比PNG加載更快,除非一些非常小的圖片踪危、但對于友好的PNG圖片蔬浙,一些中大尺寸的圖效果還 是很好的。

所以對于之前的圖片傳送器程序來說贞远,JPEG會是個不錯的選擇畴博。如果用JPEG的話,一些多線程和緩存策略都沒必要了兴革。

JPEG圖片并不是所有情況都適用绎晃。如果圖片需要一些透明效果,或者壓縮之 后細(xì)節(jié)損耗很多杂曲,那就該考慮用別的格式了庶艾。蘋果在iOS系統(tǒng)中對PNGJPEG都 做了一些優(yōu)化,所以普通情況下都應(yīng)該用這種格式擎勘。也就是說在一些特殊的情況下 才應(yīng)該使用別的格式咱揍。

混合圖片

對于包含透明的圖片來說,最好是使用壓縮透明通道的PNG圖片和壓縮RGB部分的JPEG圖片混合起來加載棚饵。這就對任何格式都適用了煤裙,而且無論從質(zhì)量還是文 件尺寸還是加載性能來說都和PNGJPEG的圖片相近。

JPEG 2000

除了JPEGPNG之外iOS還支持別的一些格式噪漾,例如TIFFGIF硼砰,但是由于他們 質(zhì)量壓縮得更厲害,性能比JPEGPNG糟糕的多欣硼,所以大多數(shù)情況并不用考慮题翰。

但是iOS之后,蘋果低調(diào)添加了對JPEG 2000圖片格式的支持,所以大多數(shù)人并 不知道豹障。它甚至并不被Xcode很好的支持 - JPEG 2000圖片都沒在Interface Builder中顯示冯事。

但是JPEG 2000圖片在(設(shè)備和模擬器)運(yùn)行時會有效,而且比JPEG質(zhì)量更好血公,同樣也對透明通道有很好的支持昵仅。但是JPEG 2000圖片在加載和顯示圖片方面明顯要比PNGJPEG慢得多,所以對圖片大小比運(yùn)行效率更敏感的時候累魔,使用它是一個不錯的選擇摔笤。

但仍然要對JPEG 2000保持關(guān)注,因為在后續(xù)iOS版本說不定就對它的性能做提升薛夜,但是在現(xiàn)階段籍茧,混合圖片對更小尺寸和質(zhì)量的文件性能會更好版述。

PVRTC

當(dāng)前市場的每個iOS設(shè)備都使用了Imagination Technologies PowerVR圖像芯片 作為GPU梯澜。PowerVR芯片支持一種叫做PVRTC(PowerVR Texture Compression)的標(biāo)準(zhǔn)圖片壓縮。

iOS上可用的大多數(shù)圖片格式不同渴析,PVRTC不用提前解壓就可以被直接繪制到 屏幕上晚伙。這意味著在加載圖片之后不需要有解壓操作,所以內(nèi)存中的圖片比其他圖片格式大大減少了(這取決于壓縮設(shè)置俭茧,大概只有1/60那么大)咆疗。

但是PVRTC仍然有一些弊端:

  • 盡管加載的時候消耗了更少的RAMPVRTC文件比JPEG要大母债,有時候甚至比 PNG還要大(這取決于具體內(nèi)容)午磁,因為壓縮算法是針對于性能,而不是文件尺寸毡们。

  • PVRTC必須要是二維正方形迅皇,如果源圖片不滿足這些要求,那必須要在轉(zhuǎn)換成PVRTC的時候強(qiáng)制拉伸或者填充空白空間衙熔。

  • 質(zhì)量并不是很好登颓,尤其是透明圖片。通澈炻龋看起來更像嚴(yán)重壓縮的JPEG文件框咙。

  • PVRTC不能用Core Graphics繪制,也不能在普通的UIImageView顯示痢甘,也 不能直接用作圖層的內(nèi)容喇嘱。你必須要用作OpenGL紋理加載PVRTC圖片,然后 映射到一對三角板來在 CAEAGLLayer或者 GLKView中顯示塞栅。
  • 創(chuàng)建一個OpenGL紋理來繪制PVRTC圖片的開銷相當(dāng)昂貴者铜。除非你想把所有圖 片繪制到一個相同的上下文,不然這完全不能發(fā)揮PVRTC的優(yōu)勢默辨。
  • PVRTC使用了一個不對稱的壓縮算法蜂大。盡管它幾乎立即解壓,但是壓縮過程相 當(dāng)漫長闰集。在一個現(xiàn)代快速的桌面Mac電腦上俗壹,它甚至要消耗一分鐘甚至更多來 生成一個PVRTC大圖科汗。因此在iOS設(shè)備上最好不要實時生成。

如果你愿意使用OpehGL绷雏,而且即使提前生成圖片也能忍受得了头滔,那么PVRTC將 會提供相對于別的可用格式來說非常高效的加載性能。比如涎显,可以在主線程1/60秒 之內(nèi)加載并顯示一張2048×2048PVRTC圖片(這已經(jīng)足夠大來填充一個視網(wǎng)膜 屏幕的iPad了)坤检,這就避免了很多使用線程或者緩存等等復(fù)雜的技術(shù)難度。

總結(jié)

在這章中期吓,我們研究了和圖片加載解壓相關(guān)的性能問題早歇,并延展了一系列解決方案。

iOS核心動畫高級技巧--目錄

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末讨勤,一起剝皮案震驚了整個濱河市箭跳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌潭千,老刑警劉巖谱姓,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異刨晴,居然都是意外死亡屉来,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門狈癞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茄靠,“玉大人,你說我怎么就攤上這事亿驾∴谇” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵莫瞬,是天一觀的道長儡蔓。 經(jīng)常有香客問我,道長疼邀,這世上最難降的妖魔是什么喂江? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮旁振,結(jié)果婚禮上获询,老公的妹妹穿的比我還像新娘涨岁。我一直安慰自己,他們只是感情好吉嚣,可當(dāng)我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布梢薪。 她就那樣靜靜地躺著,像睡著了一般尝哆。 火紅的嫁衣襯著肌膚如雪秉撇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天秋泄,我揣著相機(jī)與錄音琐馆,去河邊找鬼。 笑死恒序,一個胖子當(dāng)著我的面吹牛瘦麸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播歧胁,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼滋饲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了与帆?” 一聲冷哼從身側(cè)響起了赌,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎玄糟,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袄秩,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡阵翎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了之剧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片郭卫。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖背稼,靈堂內(nèi)的尸體忽然破棺而出贰军,到底是詐尸還是另有隱情,我是刑警寧澤蟹肘,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布词疼,位于F島的核電站,受9級特大地震影響帘腹,放射性物質(zhì)發(fā)生泄漏贰盗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一阳欲、第九天 我趴在偏房一處隱蔽的房頂上張望舵盈。 院中可真熱鬧陋率,春花似錦、人聲如沸秽晚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赴蝇。三九已至狸页,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扯再,已是汗流浹背芍耘。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留熄阻,地道東北人斋竞。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像秃殉,于是被迫代替她去往敵國和親坝初。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,494評論 2 348

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