【IOS開發(fā)基礎(chǔ)系列】SDWebImageDownloader專題

1 機(jī)制原理

????????SDWebImage是一個(gè)很厲害的圖片緩存的框架葫笼。既ASIHttp+AsyncImage之后祝闻,我一直使用AFNetworking集成的UIImageView+AFNetworking.h碳抄,但后者對(duì)于圖片的緩存實(shí)際應(yīng)用的是NSURLCache自帶的cache機(jī)制草添。而NSURLCache每次都要把緩存的raw ?data 再轉(zhuǎn)化為UIImage酪劫,就帶來(lái)了數(shù)據(jù)處理和內(nèi)存方面的更多操作。具體的比較在這里珊蟀。

????????SDWebImage提供了如下三個(gè)category來(lái)進(jìn)行緩存菊值。

??????MKAnnotationView(WebCache)

??????UIButton(WebCache)

????? UIImageView(WebCache)

????????以最為常用的UIImageView為例:

????1、UIImageView+WebCache: setImageWithURL: placeholderImage: options:?

????先顯示 placeholderImage,同時(shí)由SDWebImageManager 根據(jù) URL 來(lái)在本地查找圖片腻窒。

????2昵宇、SDWebImageManager:?downloadWithURL: delegate: options: userInfo:

????SDWebImageManager是將UIImageView+WebCache同SDImageCache鏈接起來(lái)的類, ????SDImageCache:queryDiskCacheForKey:delegate:userInfo:

????用來(lái)從緩存根據(jù)CacheKey查找圖片是否已經(jīng)在緩存中

????3儿子、如果內(nèi)存中已經(jīng)有圖片緩存瓦哎,?SDWebImageManager會(huì)回調(diào)SDImageCacheDelegate: imageCache: didFindImage: forKey: userInfo:

????4、而 UIImageView+WebCache 則回調(diào)SDWebImageManagerDelegate:? webImageManager: didFinishWithImage: 來(lái)顯示圖片典徊。

????5、如果內(nèi)存中沒(méi)有圖片緩存恩够,那么生成 NSInvocationOperation 添加到隊(duì)列卒落,從硬盤查找圖片是否已被下載緩存。

????6蜂桶、根據(jù) URLKey 在硬盤緩存目錄下嘗試讀取圖片文件儡毕。這一步是在 NSOperation 進(jìn)行的操作,所以回主線程進(jìn)行結(jié)果回調(diào)?notifyDelegate:扑媚。

????7腰湾、如果上一操作從硬盤讀取到了圖片,將圖片添加到內(nèi)存緩存中(如果空閑內(nèi)存過(guò)小疆股,會(huì)先清空內(nèi)存緩存)费坊。SDImageCacheDelegate 回調(diào)?imageCache:didFindImage:forKey:userInfo:。進(jìn)而回調(diào)展示圖片旬痹。

????8附井、如果從硬盤緩存目錄讀取不到圖片,說(shuō)明所有緩存都不存在該圖片两残,需要下載圖片永毅,回調(diào)imageCache:didNotFindImageForKey:userInfo:。

????9人弓、共享或重新生成一個(gè)下載器?SDWebImageDownloader?開始下載圖片沼死。

????10、圖片下載由 NSURLConnection 來(lái)做崔赌,實(shí)現(xiàn)相關(guān) delegate 來(lái)判斷圖片下載中意蛀、下載完成和下載失敗。

????11健芭、connection:didReceiveData:?中利用 ImageIO 做了按圖片下載進(jìn)度加載效果浸间。

????12、connectionDidFinishLoading:?數(shù)據(jù)下載完成后交給?SDWebImageDecoder?做圖片解碼處理吟榴。

????13魁蒜、圖片解碼處理在一個(gè) NSOperationQueue 完成,不會(huì)拖慢主線程 UI。如果有需要對(duì)下載的圖片進(jìn)行二次處理兜看,最好也在這里完成锥咸,效率會(huì)好很多。

????14细移、在主線程?notifyDelegateOnMainThreadWithInfo:?宣告解碼完成搏予,imageDecoder: didFinishDecodingImage: userInfo:?回調(diào)給 SDWebImageDownloader。

????15弧轧、imageDownloader:didFinishWithImage:?回調(diào)給 SDWebImageManager 告知圖片下載完成雪侥。

????16、通知所有的 downloadDelegates 下載完成精绎,回調(diào)給需要的地方展示圖片速缨。

????17、將圖片保存到 SDImageCache 中代乃,內(nèi)存緩存和硬盤緩存同時(shí)保存旬牲。

????18、寫文件到硬盤在單獨(dú) NSInvocationOperation 中完成搁吓,避免拖慢主線程原茅。

????19、如果是在iOS上運(yùn)行堕仔,SDImageCache 在初始化的時(shí)候會(huì)注冊(cè)notification 到?UIApplicationDidReceiveMemoryWarningNotification以及?UIApplicationWillTerminateNotification,在內(nèi)存警告的時(shí)候清理內(nèi)存圖片緩存擂橘,應(yīng)用結(jié)束的時(shí)候清理過(guò)期圖片。

????20摩骨、SDWebImagePrefetcher?可以預(yù)先下載圖片贝室,方便后續(xù)使用。


2 開發(fā)技巧

2.1 常見問(wèn)題

2.1.1 下載大量圖片導(dǎo)致內(nèi)存告警

2.1.1.1 問(wèn)題原因

????1仿吞、CGBitmapContextCreateImage繪制的圖片會(huì)造成內(nèi)存無(wú)法釋放滑频,應(yīng)該換用CGDataProviderCreateWithCFData;

????2唤冈、加載大量圖片時(shí)峡迷,SD會(huì)將圖片進(jìn)行解壓(加快渲染速度,但是內(nèi)存會(huì)增大差不多一倍)你虹,然后將解壓后的Image數(shù)據(jù)緩存在內(nèi)存中绘搞,從而導(dǎo)致內(nèi)存暴漲;


以下代碼具有內(nèi)存泄露問(wèn)題:

??? // 原始方案

??? UIGraphicsBeginImageContextWithOptions(imageSize,YES, 0);

??? [image drawInRect: imageRect];

??? UIImage *imgData = UIGraphicsGetImageFromCurrentImageContext();

??? UIGraphicsEndImageContext();


??? return imgData;


//? ?改進(jìn)方案1

//??????? CGImageRef imgRef =CGImageCreateWithImageInRect(image.CGImage,CGRectMake(0,0,image.size.width,image.size.height));

//???

//???????UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0);

//??????? CGContextRef context = UIGraphicsGetCurrentContext();

//??????? CGContextDrawImage(context, imageRect, imgRef);

//??? //???[image drawInRect: imageRect];

//??????? UIImage *imgData = UIGraphicsGetImageFromCurrentImageContext();

//??????? UIGraphicsEndImageContext();

//??????? CGImageRelease(imgRef);

//??????? UIImage *data = [self verticallyFlipImage: imgData];

//???????

//??????? return data;


??? //方案二傅物,內(nèi)存有釋放夯辖,掛機(jī)

//???UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);? ?

//??? CGContextRef context =UIGraphicsGetCurrentContext();

//??? CGRect rect = CGRectMake(0, 0,imageSize.width * [UIScreen mainScreen].scale, imageSize.height * [UIScreenmainScreen].scale);

//??? // draw alpha-mask

////??? CGContextSetBlendMode(context,kCGBlendModeNormal);

//??? CGContextDrawImage(context, rect,image.CGImage);

//??? // draw tint color, preserving alpha valuesof original image

////??? CGContextSetBlendMode(context,kCGBlendModeSourceIn);

//

//??? CGContextFillRect(context, rect);

//???

//??? //Set the original greyscale template asthe overlay of the new image

//??? UIImage *imgData = [selfverticallyFlipImage:image];

//??? [imgData drawInRect:imageRect];

//??? UIImage *colouredImage =UIGraphicsGetImageFromCurrentImageContext();

//??? UIGraphicsEndImageContext();

//??? colouredImage = [selfverticallyFlipImage:colouredImage];

//??? CGContextRelease(context);

//???

//??? return colouredImage;


??? //方案三,內(nèi)存沒(méi)釋放

//??? CGFloat targetWidth = imageSize.width *[UIScreen mainScreen].scale;

//??? CGFloat targetHeight = imageSize.height *[UIScreen mainScreen].scale;

//??? CGImageRef imageRef = [image CGImage];?

//??? CGBitmapInfo bitmapInfo =CGImageGetBitmapInfo(imageRef);??

//??? CGColorSpaceRef colorSpaceInfo =CGImageGetColorSpace(imageRef);

//??? CGContextRef bitmapContext;

//??? bitmapContext = CGBitmapContextCreate(NULL,targetWidth, targetHeight,CGImageGetBitsPerComponent(imageRef),CGImageGetBytesPerRow(imageRef),colorSpaceInfo, bitmapInfo);

//??? CGContextDrawImage(bitmapContext,CGRectMake(0, 0, targetWidth, targetHeight), imageRef);

//??? CGImageRef imgref =CGBitmapContextCreateImage(bitmapContext);

//??? UIImage* newImage = [UIImage imageWithCGImage: imgref];

//??? CGColorSpaceRelease(colorSpaceInfo);

//??? CGContextRelease(bitmapContext);

//??? CGImageRelease(imgref);

//???

//???return newImage;


2.1.1.2 方案一:修改源代碼董饰,入緩存前做數(shù)據(jù)壓縮

http://my.oschina.net/u/1244672/blog/510379

????????SDWebImage有一個(gè)SDWebImageDownloaderOperation類來(lái)執(zhí)行下載操作的蒿褂。里面有個(gè)下載完成的方法:

- (void) connectionDidFinishLoading: (NSURLConnection*)aConnection {

????SDWebImageDownloaderCompletedBlockcompletionBlock = self.completedBlock;

????@synchronized(self) {

????????CFRunLoopStop(CFRunLoopGetCurrent());

????????self.thread =?nil;

????????self.connection= nil;

????????[[NSNotificationCenter defaultCenter] postNotificationName: SDWebImageDownloadStopNotification object: nil];

????}


????if(![[NSURLCache sharedURLCache] cachedResponseForRequest: _request]) {

????????responseFromCached= NO;

????}


????if(completionBlock)

????{

????????if(self.options & SDWebImageDownloaderIgnoreCachedResponse &&responseFromCached) {

????????????completionBlock(nil, nil, nil, YES);

????????}

????????else {

????????????UIImage *image= [UIImage sd_imageWithData: self.imageData];

????????????NSString *key= [[SDWebImageManager sharedManager] cacheKeyForURL: self.request.URL];

????????????image = [self scaledImageForKey: key image: image];


????????????// Do not force decoding animated GIFs

????????????if(!image.images) {

????????????????image =[UIImage decodedImageWithImage: image];

????????????}

????????????if(CGSizeEqualToSize(image.size, CGSizeZero)) {

????????????????completionBlock(nil, nil, [NSError errorWithDomain: @"SDWebImageErrorDomain" code: 0 userInfo: @{NSLocalizedDescriptionKey : @"Downloaded image has 0pixels"}], YES);

????????????}

????????????else {

????????????????completionBlock(image, self.imageData, nil, YES);

????????????}

????????}

????}

????self.completionBlock= nil;

????[self done];

}


其中圆米,UIImage *image = [UIImage sd_imageWithData: self.imageData]; 就是將data轉(zhuǎn)換成image。

再看看sd_imageWithData:這個(gè)方法:

+ (UIImage*) sd_imageWithData: (NSData *)data {

????UIImage *image;

????NSString *imageContentType = [NSData sd_contentTypeForImageData: data];

????if ([imageContentType isEqualToString: @"image/gif"]) {

????????image =[UIImage sd_animatedGIFWithData: data];

????}

#ifdef?SD_WEBP

????else if([imageContentType isEqualToString: @"image/webp"])

????{

????????image =[UIImage sd_imageWithWebPData: data];

????}

#endif

????else {

????????image = [[UIImage alloc] initWithData: data];

????????UIImageOrientationorientation = [self sd_imageOrientationFromImageData: data];

????????if(orientation != UIImageOrientationUp) {

????????????image =[UIImage imageWithCGImage: image.CGImage scale: image.scale orientation: orientation];

????????}

????}


????return image;

}

????????這個(gè)方法在UIImage+MultiFormat里面啄栓,是UIImage的一個(gè)類別處理娄帖。這句話很重要image =[[UIImage alloc] initWithData:data]; SDWebImage把下載下來(lái)的data直接轉(zhuǎn)成image,然后沒(méi)做等比縮放直接存起來(lái)使用昙楚。所以近速,我們只需要在這邊做處理即可:

????????UIImage+MultiFormat添加一個(gè)方法:

+ (UIImage *) compressImageWith: (UIImage *)image

{

????float imageWidth = image.size.width;

????float imageHeight = image.size.height;

????float width =640;

????float height =image.size.height / (image.size.width/width);

????float widthScale = imageWidth / width;

????float heightScale = imageHeight / height;


????// 創(chuàng)建一個(gè)bitmap的context并把它設(shè)置成為當(dāng)前正在使用的context

????UIGraphicsBeginImageContext(CGSizeMake(width, height));


????if (widthScale> heightScale) {

????????[image drawInRect: CGRectMake(0, 0, imageWidth / heightScale , height)];

????}

????else {

????????[image drawInRect: CGRectMake(0, 0, width , imageHeight / widthScale)];

????}


????// 從當(dāng)前context中創(chuàng)建一個(gè)改變大小后的圖片

????UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

????// 使當(dāng)前的context出堆棧

????UIGraphicsEndImageContext();


????return newImage;

}


????????然后在image =[[UIImage alloc] initWithData: data];下面調(diào)用以下:

????if(data.length/1024 > 1024) {

????????image = [self compressImageWith: image];

????}


????????當(dāng)data大于1M的時(shí)候做壓縮處理。革命尚未成功堪旧,還需要一步處理削葱。在SDWebImageDownloaderOperation的connectionDidFinishLoading方法里面的:

????????UIImage *image= [UIImage sd_imageWithData: self.imageData];


//將等比壓縮過(guò)的image在賦在轉(zhuǎn)成data賦給self.imageData

NSData *data = UIImageJPEGRepresentation(image, 1);

self.imageData = [NSMutableData dataWithData: data];


2.1.1.3 方案二:設(shè)置全局緩存大小

http://www.myexception.cn/swift/2033029.html

????1、首先在appdelegate方法didFinishLaunchingWithOptions

SDImageCache.sharedImageCache().maxCacheSize=1024*1024*8設(shè)置一下最大的緩存大小淳梦。

????2析砸、在appdelegate?applicationDidReceiveMemoryWarning里加入

SDImageCache.sharedImageCache().clearMemory()

SDWebImageManager.sharedManager().cancelAll()


2.1.1.4 方案三:定時(shí)清理內(nèi)存緩存

http://www.bubuko.com/infodetail-956863.html

????????經(jīng)過(guò)嘗試,發(fā)現(xiàn)了一個(gè)最簡(jiǎn)單的完美解決該問(wèn)題的方法

????????在使用SDWebImage加載較多圖片造成內(nèi)存警告時(shí)谭跨,定期調(diào)用

?[[SDImageCache sharedImageCache] setValue: nil forKey: @"memCache"];


2.1.1.5 方案四(不推薦):修復(fù)SD庫(kù)代碼干厚,不做解壓李滴,直接返回壓縮的原圖

2.1.1.6 方案五(推薦):使用CGDataProviderRef進(jìn)行圖形解壓重繪

iOS開發(fā)中界面展示大圖片時(shí)UIImage的性能有關(guān)問(wèn)題

http://www.myexception.cn/operating-system/578931.html


#import "SDWebImageDecoder.h"


@implementation UIImage (ForceDecode)


+ (UIImage*) decodedImageWithImage: (UIImage*)image {

??? if (image.images) {

???????// Do not decode animated images

???????return image;

??? }


??? //僅僅作為臨時(shí)應(yīng)付方案

????//??? return image;


??? UIImage *decompressedImage;


????@autoreleasepool{

????????//核心代碼螃宙,可以解決內(nèi)存未釋放問(wèn)題

??????? NSData *data = UIImageJPEGRepresentation(image, 1);

??????? CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

??????? CGImageRefimageRef = CGImageCreateWithPNGDataProvider(dataProvider, NULL, NO,

kCGRenderingIntentDefault);


????//??? CGImageRef imageRef = image.CGImage;

??? CGSizeimageSize = CGSizeMake(CGImageGetWidth(imageRef),CGImageGetHeight(imageRef));

??? CGRect imageRect = (CGRect){.origin = CGPointZero, .size=imageSize};

??? CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

??? CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);


??? intinfoMask = (bitmapInfo & kCGBitmapAlphaInfoMask);

??? BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone || infoMask ==kCGImageAlphaNoneSkipFirst || infoMask ==kCGImageAlphaNoneSkipLast);


??? // CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB.

??? // https://developer.apple.com/library/mac/#qa/qa1037/_index.html

??? if(infoMask == kCGImageAlphaNone&& CGColorSpaceGetNumberOfComponents(colorSpace)

> 1) {

??????? // Unset the old alpha info.

??????? bitmapInfo &= ~kCGBitmapAlphaInfoMask;


??????? // Set noneSkipFirst.

??????? bitmapInfo |= kCGImageAlphaNoneSkipFirst;

??? }

? ? ?// Some PNGs tell us they have alpha but only 3 components. Odd.

??? else if(!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace)

== 3) {

??????? // Unset the old alpha info.

??????? bitmapInfo &= ~kCGBitmapAlphaInfoMask;

??????? bitmapInfo |= kCGImageAlphaPremultipliedFirst;

??? }


??? // It calculates the bytes-per-row based on the bitsPerComponent and width arguments.

??? CGContextRef context = CGBitmapContextCreate(NULL, imageSize.width, imageSize.height,? CGImageGetBitsPerComponent(imageRef), 0, colorSpace, bitmapInfo);

??? CGColorSpaceRelease(colorSpace);


??? // If failed, return undecompressed image

??? if(!context)?

????????return image;


??? CGContextDrawImage(context,imageRect, imageRef);

??? CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);

??? CGContextRelease(context);

??? decompressedImage = [UIImage imageWithCGImage: decompressedImageRef scale: image.scale orientation: image.imageOrientation];

??? CGImageRelease(decompressedImageRef);

}


//??? CVPixelBufferRef pixelBuffer;

//???CreateCGImageFromCVPixelBuffer(pixelBuffer,&decompressedImageRef);

//??? CGImage *cgImage =CGBitmapContextCreateImage(context);

//??? CFDataRef dataRef =CGDataProviderCopyData(CGImageGetDataProvider(cgImage));

//??? CGImageRelease(cgImage);

//??? image->imageRef = dataRef;

//??? image->image =CFDataGetBytePtr(dataRef);


??? return decompressedImage;

}

3 參考鏈接

(GOOD)iOS開發(fā)中界面展示大圖片時(shí)UIImage的性能有關(guān)問(wèn)題

http://www.myexception.cn/operating-system/578931.html


(Good)iPhone - UIImage Leak, CGBitmapContextCreateImage Leak

http://stackoverflow.com/questions/1427478/iphone-uiimage-leak-cgbitmapcontextcreateimage-leak


Another iPhone - CGBitmapContextCreateImage Leak

http://stackoverflow.com/questions/1434714/another-iphone-cgbitmapcontextcreateimage-leak


UIGraphicsBeginImageContext vs CGBitmapContextCreate

http://stackoverflow.com/questions/4683448/uigraphicsbeginimagecontext-vs-cgbitmapcontextcreate


iPhone - CGBitmapContextCreateImage Leak, Anyone else withthis problem?

http://stackoverflow.com/questions/1431566/iphone-cgbitmapcontextcreateimage-leak-anyone-else-with-this-problem


Build and Analyze false positive on leak detection?

http://stackoverflow.com/questions/8438249/build-and-analyze-false-positive-on-leak-detection


iPhone - Multiple CGBitmapContextCreateImage Calls -ObjectAlloc climbing

http://stackoverflow.com/questions/1436465/iphone-multiple-cgbitmapcontextcreateimage-calls-objectalloc-climbing


(Good)ios開發(fā)圖片處理,內(nèi)存泄露

http://www.oschina.net/question/736524_69802


主題: CGBitmapContextCreateImage(bitmap)內(nèi)存泄露問(wèn)題處理

http://www.cocoachina.com/bbs/read.php?tid=31835


iOS異步圖片加載優(yōu)化與常用開源庫(kù)分析

http://luoyibu.com/2015/05/12/iOS異步圖片加載優(yōu)化與常用開源庫(kù)分析/


主題:圖片處理開源函數(shù)ImageProcessing? CGDataProviderCreateWithData Bug修復(fù)

http://www.cocoachina.com/bbs/read.php?tid=116149


CGDataProviderCreateWithData對(duì)內(nèi)存數(shù)據(jù)的釋放

http://www.taofengping.com/2012/11/04/cgdataprovidercreatewithdata_memory_release/#.VmpqgoSitZE


IOS7.x下UIGraphicsGetImageFromCurrentImageContext引發(fā)內(nèi)存暴漲所坯,導(dǎo)致應(yīng)用被結(jié)束掉

http://blog.163.com/l1_jun/blog/static/1438638820155593641529/


在iOS中與CGContextRef的內(nèi)存泄漏

http://www.itstrike.cn/Question/55b86ce7-dfba-4548-a103-22dc5317420a.html


Quartz 2D (ProgrammingWithQuartz) note

http://renxiangzyq.iteye.com/blog/1188025


使用AFNetworking,SDWebimage和OHHTTPStubs

http://blog.shiqichan.com/using-afnetworking-sdwebimage-and-ohhttpstubs/


SDWebImage緩存圖片的機(jī)制(轉(zhuǎn))

http://blog.csdn.net/zhun36/article/details/8900327


近來(lái)一個(gè)swift項(xiàng)目用uicollectionview 用sdwebimage 加載圖片谆扎,發(fā)生內(nèi)存猛增,直接閃退的情況芹助,簡(jiǎn)單說(shuō)一下解決方案

http://www.myexception.cn/swift/2033029.html


關(guān)于SDWebImage加載高清圖片導(dǎo)致app崩潰的問(wèn)題

http://www.bubuko.com/infodetail-956863.html


SDWebImage加載大圖導(dǎo)致的內(nèi)存警告問(wèn)題

http://blog.csdn.net/richer1997/article/details/43481959


解決MWPhotoBrowser中的SDWebImage加載大圖導(dǎo)致的內(nèi)存警告問(wèn)題

http://my.oschina.net/u/1244672/blog/510379


使用SDWebImage加載大量圖片后造成內(nèi)存泄露的解決辦法

http://www.bubuko.com/infodetail-985746.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末堂湖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子状土,更是在濱河造成了極大的恐慌无蜂,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒙谓,死亡現(xiàn)場(chǎng)離奇詭異斥季,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)累驮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門酣倾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人谤专,你說(shuō)我怎么就攤上這事躁锡。” “怎么了置侍?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵映之,是天一觀的道長(zhǎng)拦焚。 經(jīng)常有香客問(wèn)我,道長(zhǎng)惕医,這世上最難降的妖魔是什么耕漱? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮抬伺,結(jié)果婚禮上螟够,老公的妹妹穿的比我還像新娘。我一直安慰自己峡钓,他們只是感情好妓笙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著能岩,像睡著了一般寞宫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拉鹃,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天辈赋,我揣著相機(jī)與錄音,去河邊找鬼膏燕。 笑死邻储,一個(gè)胖子當(dāng)著我的面吹牛檩奠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼毡琉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼谜嫉!你這毒婦竟也來(lái)了骄酗?” 一聲冷哼從身側(cè)響起嘱兼,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎及舍,沒(méi)想到半個(gè)月后未辆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锯玛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年咐柜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片更振。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡炕桨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出肯腕,到底是詐尸還是另有隱情献宫,我是刑警寧澤,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布实撒,位于F島的核電站姊途,受9級(jí)特大地震影響涉瘾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捷兰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一立叛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贡茅,春花似錦秘蛇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至驹沿,卻和暖如春艘策,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背渊季。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工朋蔫, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人却汉。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓驯妄,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親病涨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子富玷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

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