使用Xcode8的Instruments檢測解決iOS內(nèi)存泄露

提供了基于Swift3.0模仿的新浪微博的Demo母廷,大家可以下載看一看:基于Swift3.0高仿的微博客戶端,里面針對于微博首頁的復(fù)雜頁面的優(yōu)化做了很多的處理蛛蒙,頁面的FPS 一直保持在59 ~ 60 眼滤「墙茫看下demo的效果:

FPS測試.gif

CPU 和GPU
關(guān)于繪圖和動畫有兩種處理方式CPU(中央處理器)和GPU(圖形處理器)厌丑,CPU的工作都在軟件層面,而GPU的在硬件層面匹耕【矍耄總的來說,可以使用CPU做任何事情稳其,但是對于圖像的處理驶赏,通常GPU會更快,因?yàn)镚PU使用圖像對高度并行浮點(diǎn)運(yùn)算做了優(yōu)化(盡管我也不知道是什么鬼既鞠?煤傍?),所以嘱蛋,我們想盡可能的把屏幕渲染的工作交給硬件去處理蚯姆,而問題在于GPU并沒有無限制處理的性能,一旦資源用盡洒敏,即使CPU并沒有完全占用龄恋,GPU性能還是會下降。所以凶伙,目前大多的性能優(yōu)化都是關(guān)于智能利用GPU和CPU郭毕,平衡它們之間工作負(fù)載。
測量函荣,而不是猜測
現(xiàn)在知道哪些可能會影響性能显押,該如何修復(fù)呢链韭?有許多傳統(tǒng)的詭計來優(yōu)化,但如果盲目使用的話煮落,可能會造成更多性能上的問題敞峭,而不是優(yōu)化了如何正確的測量而不是猜測這點(diǎn)很重要,根據(jù)性能相關(guān)知識寫出的代碼不同于倉促優(yōu)化蝉仇,前者是正確的姿勢旋讹,后者則是在浪費(fèi)生命那改如何測量,第一步就是確保在真實(shí)環(huán)境下測試你的程序
真機(jī)測試轿衔,而不是模擬器
當(dāng)你開始做一些性能方面的工作時候沉迹,一定要在真機(jī)上測試,而不是模擬器害驹,模擬器雖然可以加快開發(fā)效率鞭呕,但卻不能準(zhǔn)確提供真機(jī)的性能參數(shù)模擬器運(yùn)行在Mac上,然而Mac上的cpu比ios設(shè)備要快很多宛官,相反葫松,Mac上的GPU和ios設(shè)備上的不一樣,模擬器不得已需要在軟件層面(CPU)模擬ios設(shè)備底洗,所以GPU的相關(guān)操作在模擬器上面運(yùn)行的會更慢另一件重要的就是性能測試的時候一定要用發(fā)布配置腋么,而不是調(diào)試模式,因?yàn)楫?dāng)用發(fā)布環(huán)境打包的時候亥揖,編譯器會引入一些提高性能的優(yōu)化珊擂,比如:去除調(diào)試符號或者移除并重新組織代碼,因?yàn)榭梢宰约鹤龅竭@些费变,比如禁用NSlog摧扇、print語句,因?yàn)?挚歧,只需要關(guān)心發(fā)布性能扛稽。
測試幀率
可以在程序中使用CADisplayLink來測量幀率,在屏幕上顯示出來,我用Swift3.0模仿YY大神的代碼寫了一個簡單的FPS指示器 YWFPSLabel,使用CADisplayLink監(jiān)視FPS數(shù)值昼激,日常開發(fā)的時候庇绽,可以有直接的體現(xiàn)锡搜,不用再靠猜了...YWFPSLabel集成也很方便,在AppDelegate的application方法里加下面兩句即可
let FPSLab = YWFPSLabel(frame: CGRect()) UIApplication.shared.keyWindow!.addSubview(FPSLab)

不知道大家有木有看到頭部那個小label啊~~~但是應(yīng)用內(nèi)的FPS顯示并不能完全真實(shí)的測量出性能橙困,因?yàn)樗鼉H僅能測試出應(yīng)用內(nèi)的幀率,還有很多是動畫都是在應(yīng)用外發(fā)生(在渲染進(jìn)程中處理)耕餐,但應(yīng)用內(nèi)FPS計數(shù)可以對一些性能問題提供參考凡傅,一旦找到問題,需要更多的精確詳細(xì)信息來定位問題所在肠缔,我們就要使用Instuments了夏跷,它可以看到更多準(zhǔn)確是信息哼转,查看到所有與顯示的數(shù)據(jù)。
Instuments
Instuments是Xcode套件中沒有被充分利用的工具槽华,很多iOS開發(fā)者從來沒用過Instrument壹蔓,特別是通過短暫培訓(xùn)出來的同學(xué)們,所以猫态,很多面試官也會問性能條調(diào)優(yōu)方面的知識佣蓉,來判斷面試的同學(xué)是否真正應(yīng)用對年開發(fā)經(jīng)驗(yàn)。
Activity Monitor
個人覺的很像Windows的任務(wù)管理器亲雪,可以查看所有的進(jìn)程勇凭,以及進(jìn)程的內(nèi)存、cpu使用百分比等數(shù)據(jù)等义辕,就不多介紹了虾标,打開一看大概就知道怎么回事

Allocations
管理內(nèi)存是app開發(fā)中最重要的一個方面,對于開發(fā)者來說灌砖,在程序架構(gòu)中減少內(nèi)存的使用通常都是使用Allocations去定位和找出減少內(nèi)存使用的方式接下來璧函,談一下內(nèi)存泄漏的兩種情況

第一種:為對象A申請了內(nèi)存空間,之后再也沒用過對象A基显,也沒釋放過A導(dǎo)致內(nèi)存泄漏柳譬,這種是Leaked Memory內(nèi)存泄漏

第二種:類似于遞歸,不斷地申請內(nèi)存空間導(dǎo)致的內(nèi)存泄漏续镇,這種情況是Abandoned Momory此工具可以讓開發(fā)者很好的了解每個方法占用內(nèi)存的情況美澳,并定位相關(guān)的代碼
Allocations查看方法占用內(nèi)存.png

右鍵就可以打開Xcode自動定位到相關(guān)占用內(nèi)存方法的代碼上

定位到相關(guān)代碼.png

第二種情況可以根據(jù)下圖的操作清晰的找到對用的代碼問題


定位Abandoned Momory.png

解釋一下,第二種情況我們應(yīng)該如何操作摸航,重復(fù)的執(zhí)行一系列的操作時候內(nèi)存不會繼續(xù)增加制跟,比如打開和關(guān)閉一個窗口,這樣的操作酱虎,每一次操作的前后雨膨,內(nèi)存應(yīng)該是相同的,通過多次循環(huán)操作读串,內(nèi)存不會遞增下去聊记,通過這種分析結(jié)果,觀察內(nèi)存分配趨勢恢暖,當(dāng)發(fā)現(xiàn)不正確的結(jié)果或者矛盾的結(jié)果排监,就可以研究是不是Abandoned Momory的問題,并可以修正這個問題了
Core Animation
之前說過自己寫的YWFPSLabel只能檢測應(yīng)用內(nèi)的FPS,而此工具考慮到了程序外的動畫杰捂,理想的FPS值為60左右舆床,過低的話就用該進(jìn)性優(yōu)化了,根據(jù)WWDC的說法,當(dāng)FPS 低于45的時候挨队,用戶就會察覺到到滑動有卡頓

Core Animation.png

圈著數(shù)字紅色方框中的數(shù)字谷暮,代表著FPS值,理論上60最佳盛垦,實(shí)際過程中59就可以了湿弦,說明就是很流暢的,說明一下操作方式:在手指不離開屏幕的情況下腾夯,上下滑動屏幕列表介紹一下Deug Display中選項(xiàng)的作用
Color Blended Layers(混合過度繪制)

打開此選項(xiàng)屏幕的效果圖如下:


Color Blended Layers.jpg

這個選項(xiàng)基于渲染程度對屏幕中的混合區(qū)域進(jìn)行綠到紅的高亮(也就是多個半透明圖層的疊加)省撑,由于重繪的原因,混合對GPU性能會有影響俯在,同時也是滑動或者動畫掉幀的罪魁禍?zhǔn)字籊PU每一幀的繪制的像素有最大限制竟秫,這個情況下可以輕易繪制整個屏幕的像素,但如果發(fā)生重疊像素的關(guān)系需要不停的重繪同一區(qū)域的跷乐,掉幀和卡頓就有可能發(fā)生GPU會放棄繪制那些完全被其他圖層遮擋的像素肥败,但是要計算出一個圖層是否被遮擋也是相當(dāng)復(fù)雜并且會消耗CPU的資源,同樣愕提,合并不同圖層的透明重疊元素消耗的資源也很大馒稍,所以,為了快速處理浅侨,一般不要使用透明圖層纽谒,1). 給View添加一個固定、不透明的顏色2). 設(shè)置opaque 屬性為true但是這對性能調(diào)優(yōu)的幫助并不大如输,因?yàn)閁IView的opaque 屬性默認(rèn)為true鼓黔,也就是說,只要不是認(rèn)為設(shè)置成透明不见,都不會出現(xiàn)圖層混合而對于UIIimageView來說澳化,不僅需要自身需要不是透明的,它的圖片也不能含有alpha通道稳吮,這也上圖9張圖片是綠色的原因缎谷,因此圖像自身的性質(zhì)也可能會對結(jié)果有影響,所以你確定自己的代碼沒問題灶似,還出現(xiàn)了混合圖層可能就是圖片的問題了而針對于屏幕中的文字高亮成紅色列林,是因?yàn)橐粵]有給文字的label增加不透明的背景顏色,而是當(dāng)UILabel內(nèi)容為中文時酪惭,label的實(shí)際渲染區(qū)域要大于label的size希痴,因?yàn)橥鈬辛艘蝗Φ年幱埃艜霈F(xiàn)圖層混合我們需要給中文的label加上如下代碼:
retweededTextLab?.layer.masksToBounds = true retweededTextLab?.backgroundColor = UIColor.groupTableViewBackground statusLab.layer.masksToBounds = true statusLab.backgroundColor = UIColor.white

看下效果圖:


圖層混合優(yōu)化.png

那些label的顏色也變成藍(lán)色的了撞蚕,這里有一點(diǎn)需要說明一下润梯,1).statusLab.layer.masksToBounds = true
單獨(dú)使用不會出現(xiàn)離屏渲染2). 如果對label設(shè)置了圓角的話,圓角部分會離屏渲染甥厦,離屏渲染的前提是位圖發(fā)生了形變
Color Hits Green and Misses Red(光柵化緩存圖層的命中情況)

這個選項(xiàng)主要是檢測我們有無濫用或正確使用layer的shouldRasterize屬性.成功被緩存的layer會標(biāo)注為綠色,沒有成功緩存的會標(biāo)注為紅色纺铭。很多視圖Layer由于Shadow、Mask和Gradient等原因渲染很高刀疙,因此UIKit提供了API用于緩存這些Layer,self.layer.shouldRasterize = true
系統(tǒng)會將這些Layer緩存成Bitmap位圖供渲染使用舶赔,如果失效時便丟棄這些Bitmap重新生成。圖層Rasterization柵格化好處是對刷新率影響較小谦秧,壞處是刪格化處理后的Bitmap緩存需要占用內(nèi)存竟纳,而且當(dāng)圖層需要縮放時,要對刪格化后的Bitmap做額外計算疚鲤。 使用這個選項(xiàng)后時锥累,如果Rasterized的Layer失效,便會標(biāo)注為紅色集歇,如果有效標(biāo)注為綠色桶略。當(dāng)測試的應(yīng)用頻繁閃現(xiàn)出紅色標(biāo)注圖層時,表明對圖層做的Rasterization作用不大诲宇。在測試的過程中,第一次加載時,開啟光柵化的layer會顯示為紅色,這是很正常的,因?yàn)檫€沒有緩存成功际歼。但是如果在接下來的測試,。例如我們來回滾動TableView時,我們?nèi)匀话l(fā)現(xiàn)有許多紅色區(qū)域,那就需要謹(jǐn)慎對待了
Color Copied Image (拷貝的圖片)

這個選項(xiàng)主要檢查我們有無使用不正確圖片格式,由于手機(jī)顯示都是基于像素的姑蓝,所以當(dāng)手機(jī)要顯示一張圖片的時候鹅心,系統(tǒng)會幫我們對圖片進(jìn)行轉(zhuǎn)化。比如一個像素占用一個字節(jié)纺荧,故而RGBA則占用了4個字節(jié)旭愧,則1920 x 1080的圖片占用了7.9M左右,但是平時jpg或者png的圖片并沒有那么大宙暇,因?yàn)樗鼈儗D片做了壓縮榕茧,但是是可逆的。所以此時客给,如果圖片的格式不正確用押,則系統(tǒng)將圖片轉(zhuǎn)化為像素的時間就有可能變長。而該選項(xiàng)就是檢測圖片的格式是否是系統(tǒng)所支持的靶剑,若是GPU不支持的色彩格式的圖片則會標(biāo)記為青色,則只能由CPU來進(jìn)行處理蜻拨。CPU被強(qiáng)制生成了一些圖片,然后發(fā)送到渲染服務(wù)器桩引,而不是簡單的指向原始圖片的的指針缎讼。我們不希望在滾動視圖的時候,CPU實(shí)時來進(jìn)行處理,因?yàn)橛锌赡軙枞骶€程。
Color Immediately (顏色立即更新)

通常 Core Animation 以每秒10此的頻率更新圖層的調(diào)試顏色坑匠,對于某些效果來說血崭,這可能太慢了,這個選項(xiàng)可以用來設(shè)置每一幀都更新(可能會影響到渲染性能,所以不要一直都設(shè)置它)
Color Misaligned Image (圖片對齊方式)

這里會高亮那些被縮放或者拉伸以及沒有正確對齊到像素邊界的圖片夹纫,即圖片Size和imageView中的Size不匹配咽瓷,會使圖過程片縮放,而縮放會占用CPU舰讹,所以在寫代碼的時候保證圖片的大小匹配好imageView茅姜,如下圖所示:圖片尺寸 170 * 220px
let imageView = UIImageView(frame: CGRect(x: 50, y: 100, width: 170, height: 220)) imageView.image = UIImage(named: "cat") view.addSubview(imageView)

蘋果的單位以點(diǎn)計算,而 imageView的尺寸是170 * 220 pt 而圖片是 170 * 220px月匣,所以相當(dāng)于在屏幕上對圖片方法了一倍钻洒,看效果圖如下:


Color Misaligned Image.png

可以看到圖片高亮成黃色顯示,更改下imageView的大小
let imageView = UIImageView(frame: CGRect(x: 50, y: 100, width: 85, height: 110)) imageView.image = UIImage(named: "cat") view.addSubview(imageView)

看下效果圖


Color Misaligned Image -2.png

當(dāng)imageView和image的大小一致的時候,就正常顯示了
Color Offscreen- Rendered Yellow (離屏渲染)

這里會把那些需要離屏渲染的到圖層高亮成黃色,而出發(fā)離屏渲染的可能有
/* 圓角處理 /view.layer.maskToBounds = truesomeView.clipsToBounds = true/ 設(shè)置陰影 /view.shadow../ 柵格化 */view.layer.shouldRastarize = true

針對柵格化處理割择,我們需要指定屏幕的分辨率
//離屏渲染 - 異步繪制 耗電 self.layer.drawsAsynchronously = true //柵格化 - 異步繪制之后 饭聚,會生成一張獨(dú)立的圖片 cell 在屏幕上滾動的時候,本質(zhì)上滾動的是這張圖片 //cell 優(yōu)化,要盡量減少圖層的數(shù)量,想當(dāng)于只有一層 //停止?jié)L動之后,可以接受監(jiān)聽 self.layer.shouldRasterize = true //使用 “柵格化” 必須指定分辨率 self.layer.rasterizationScale = UIScreen.main.scale

指定陰影的路徑任岸,可以防止離屏渲染
// 指定陰影曲線,防止陰影效果帶來的離屏渲染 imageView.layer.shadowPath = UIBezierPath(rect: imageView.bounds).cgPath

這行代碼制定了陰影路徑狡刘,如果沒有手動指定享潜,Core Animation會去自動計算,這就會觸發(fā)離屏渲染嗅蔬。如果人為指定了陰影路徑剑按,就可以免去計算,從而避免產(chǎn)生離屏渲染澜术。設(shè)置cornerRadius本身并不會導(dǎo)致離屏渲染艺蝴,但很多時候它還需要配合layer.masksToBounds = true使用。根據(jù)之前的總結(jié)鸟废,設(shè)置masksToBounds會導(dǎo)致離屏渲染猜敢。解決方案是盡可能在滑動時避免設(shè)置圓角缩擂,如果必須設(shè)置圓角计露,可以使用光柵化技術(shù)將圓角緩存起來:
// 設(shè)置圓角label.layer.masksToBounds = truelabel.layer.cornerRadius = 8label.layer.shouldRasterize = truelabel.layer.rasterizationScale = layer.contentsScale

如果界面中有很多控件需要設(shè)置圓角泞边,比如tableView中乡数,當(dāng)tableView有超過25個圓角,使用如下方法
view.layer.cornerRadius = 10view.maskToBounds = Yes

那么fps將會下降很多,特別是對某些控件還設(shè)置了陰影效果严沥,更會加劇界面的卡頓、掉幀現(xiàn)象,對于不同的控件將采用不同的方法進(jìn)行處理:1). 對于label類,可以通過CoreGraphics來畫出一個圓角的label2). 對于imageView,通過CoreGraphics對繪畫出來的image進(jìn)行裁邊處理方灾,形成一個圓角的imageView,代碼如下:
/// 創(chuàng)建圓角圖片 /// /// - parameter radius: 圓角的半徑 /// - parameter size: 圖片的尺寸 /// - parameter backColor: 背景顏色 默認(rèn) white /// - parameter lineWith: 圓角線寬 默認(rèn) 1 /// - parameter lineColor: 線顏色 默認(rèn) darkGray /// /// - returns: image func yw_drawRectWithRoundCornor(radius: CGFloat, size: CGSize, backColor: UIColor = UIColor.white, lineWith: CGFloat = 1, lineColor: UIColor = UIColor.darkGray) -> UIImage? { let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: size) UIGraphicsBeginImageContextWithOptions(rect.size, true, 0) let bezier = UIBezierPath(roundedRect: rect, byRoundingCorners: UIRectCorner.allCorners, cornerRadii: CGSize(width: radius, height: radius)) backColor.setFill() UIRectFill(rect) bezier.addClip() draw(in: rect) bezier.lineWidth = 1 lineColor.setStroke() bezier.stroke() let result = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return result }

Color Compositing Fast-Path Blue

這個選項(xiàng)會對任何直接使用OpenGL繪制的圖層進(jìn)行高亮劲腿,如果僅僅使用UIKit或者Core Animation的API,不會有任何效果矿辽,恕我才疏學(xué)淺,所以,我在測試的時候嘱根,確實(shí)在屏幕上沒有任何反應(yīng)的凑保,openGL 繪制芝此,我也不會,所以评肆,就不知道到底會有什么效果了糟港,哪位大神會的話攀操,貼段代碼院仿,給我試試啊~~~
Flash Updated Regions (Core Graphics 繪制的圖層)

此選項(xiàng)會對重繪的內(nèi)容進(jìn)行高亮成黃色秸抚,也就是軟件層面使用Core Graphics 繪制的圖層。我測試的時候歹垫,好像有點(diǎn)問題剥汤,這種解釋,不知道是不是我寫代碼的問題排惨,所以吭敢,就不多說了
上面說的這些高亮圖層,幾個常用的選項(xiàng)在模擬器里面可以直接調(diào)試暮芭,非常方便


模擬器高亮圖層.png

紅框中的選項(xiàng)鹿驼,上面都有解釋,這里就不說了辕宏,勾選項(xiàng)畜晰,打開模擬器,一看就知道了~麻蛋瑞筐、Core Animation 部分終于扯完了凄鼻,扯了好多啊。聚假。块蚌。
Leaks

又一個灰常重要的工具,主要檢查內(nèi)存泄漏膘格,在前面Allcations里面我們提到內(nèi)存泄漏分兩種峭范,現(xiàn)在我們研究Leaked Memory, 從用戶使用角度來看瘪贱,內(nèi)存泄漏本身不會產(chǎn)生什么危害纱控,作為用戶游岳,根本感覺不到內(nèi)存泄漏的存在,真正的危害在于內(nèi)存泄漏的堆積其徙,最終會耗盡系統(tǒng)所有的內(nèi)存胚迫。我們直接看圖:


界面的介紹
在 instruments 中,雖然選擇了 Leaks 模板,但默認(rèn)情況下也會添加 Allocations 模板.基本上凡是內(nèi)存分析都會使用 Allocations 模板, 它可以監(jiān)控內(nèi)存分布情況。選中 Allocations 模板3區(qū)域會顯示隨著時間的變化內(nèi)存使用的折線圖,同時在4區(qū)域會顯示內(nèi)存使用的詳細(xì)信息,以及對象分配情況.點(diǎn)擊 Leaks 模板, 可以查看內(nèi)存泄露情況唾那。如果在3區(qū)域有 紅X 出現(xiàn), 則有內(nèi)存泄露, 4區(qū)域則會顯示泄露的對象.打用leaks進(jìn)行監(jiān)測:點(diǎn)擊泄露對象可以在(下圖)看到它們的內(nèi)存地址, 占用字節(jié), 所屬框架和響應(yīng)方法等信息.打開擴(kuò)展視圖, 可以看到右邊的跟蹤堆棧信息访锻,4 黑色代碼最有可能出現(xiàn)內(nèi)存泄漏的方法


監(jiān)測結(jié)果的分析,


Time Profiler
在開發(fā)的過程中闹获,我們經(jīng)常能感覺到期犬,點(diǎn)擊某一按鈕,或者做了某一操作避诽,有卡頓龟虎,這就是延遲,那使用此工具沙庐,就可以揪出耗時的函數(shù)鲤妥,先看一下,調(diào)試界面介紹:


time Profiler.png

根據(jù)查看的相關(guān)耗時操作拱雏,我們就可以右鍵定位當(dāng)耗時的方法:寫一個簡單例子看一下:


屏幕快照 2016-10-30 下午4.23.02.png

看上圖棉安,可以很清楚看到此方法耗時比較嚴(yán)重,右鍵打開定位到此方法的代碼:


屏幕快照 2016-10-30 下午4.24.57.png

代碼截圖如下:


屏幕快照 2016-10-30 下午4.25.06.png

這時候铸抑,我們把循環(huán)放到子線程來做
@IBAction func btnAction(_ sender: AnyObject) { let svc = SecondViewController() svc.title = "第二個頁面" //全局隊(duì)列異步執(zhí)行 DispatchQueue.global().async { for i in 0..<8888 { print(i) } } navigationController?.pushViewController(svc, animated: true) }

看效果圖:


屏幕快照 2016-10-30 下午4.33.43.png

到這里比較重要Instrument調(diào)試工具介紹的差不多了贡耽,說一個Xcode8.0新出的功能,很好用也很重要的功能:


屏幕快照 2016-10-30 下午4.40.08.png

還是以例子說說吧鹊汛,Viewcontroller里面一個button蒲赂,點(diǎn)擊跳到SecondViewcontroller,SecondViewcontroller里面有個View刁憋,view里面有個button滥嘴,button點(diǎn)擊回到ViewController,實(shí)現(xiàn)是通過view的屬性拿到SecondviewConroller的引用,pop回去子view的代碼如下:
class SubView: UIView { var delegate: SecondViewController? @IBAction func brnAction(_ sender: AnyObject) { delegate?.navigationController!.popViewController(animated: true) }}

當(dāng)我們從第二個控制器职祷,回到第一個控制器的時候氏涩,我們點(diǎn)一下,剛那個按鈕有梆,看圖:


屏幕快照 2016-10-30 下午4.47.53.png

第二個控制器和子View都內(nèi)存中是尖,我們很容易,就可以發(fā)現(xiàn)問題了泥耀,這是因?yàn)榻刃冢琒econdViewController強(qiáng)引用了SubView,而我們SubView也強(qiáng)引用了SecondViewcontroller痰催,就造成相互強(qiáng)引用兜辞,引用計數(shù)器不能為0迎瞧,不能銷毀了,我們只要把屬性前面加個weak逸吵,變成弱引用就可以了
weak var delegate: SecondViewController? @IBAction func brnAction(_ sender: AnyObject) { delegate?.navigationController!.popViewController(animated: true) }

這時候凶硅,我們從第二個控制器pop回來的時候,看下內(nèi)存:


屏幕快照 2016-10-30 下午4.54.06.png

現(xiàn)在就沒問題了扫皱,怎樣這個工具是不是挺好用啊
以上摘自iOS巫闵稹(簡書作者)http://www.reibang.com/p/05b68c84913a,請原諒我的不要臉??????

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末韩脑,一起剝皮案震驚了整個濱河市氢妈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌段多,老刑警劉巖首量,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異进苍,居然都是意外死亡加缘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門琅捏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來生百,“玉大人,你說我怎么就攤上這事柄延。” “怎么了缀程?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵搜吧,是天一觀的道長。 經(jīng)常有香客問我杨凑,道長滤奈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任撩满,我火速辦了婚禮蜒程,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘伺帘。我一直安慰自己昭躺,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布伪嫁。 她就那樣靜靜地躺著领炫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪张咳。 梳的紋絲不亂的頭發(fā)上帝洪,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天似舵,我揣著相機(jī)與錄音,去河邊找鬼葱峡。 笑死砚哗,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的砰奕。 我是一名探鬼主播频祝,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼脆淹!你這毒婦竟也來了常空?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤盖溺,失蹤者是張志新(化名)和其女友劉穎漓糙,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烘嘱,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昆禽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蝇庭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片醉鳖。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖哮内,靈堂內(nèi)的尸體忽然破棺而出盗棵,到底是詐尸還是另有隱情,我是刑警寧澤北发,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布纹因,位于F島的核電站,受9級特大地震影響琳拨,放射性物質(zhì)發(fā)生泄漏瞭恰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一狱庇、第九天 我趴在偏房一處隱蔽的房頂上張望惊畏。 院中可真熱鬧,春花似錦密任、人聲如沸颜启。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽农曲。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乳规,已是汗流浹背形葬。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留暮的,地道東北人笙以。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像冻辩,于是被迫代替她去往敵國和親猖腕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345

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