UIImageView+AFNetworking源碼解析

前言

最近在使用SDWebImage時(shí)突然想到AFNetworking也有類(lèi)似于SD中UIImageView+WebCache的功能涛舍,因此澄惊,查看了AF中相關(guān)代碼。

UIImageView+AFNetworking簡(jiǎn)單使用

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    static  NSString* ID = @"cutomeCell";
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:ID];
    
    FYXGirlItem *item = self.items[indexPath.row];
    cell.textLabel.text = item.name;
    cell.detailTextLabel.text = item.download;
    
    [cell.imageView setImageWithURL:[NSURL URLWithString:item.icon] placeholderImage:[UIImage imageNamed:@"placeholder"]];
    return cell;
}

如上所示,在使用方面與SD差別不是很大掸驱。

UIImageView+AFNetworking介紹

1)作用

  • 用于解決異步加載圖片時(shí)的卡頓問(wèn)題(例如肛搬,UITableViewCell在加載圖片時(shí)的延遲問(wèn)題)
  1. 相關(guān)的頭文件和.m文件

① UIImageView+AFNetworking.h / UIImageView+AFNetworking.m(用戶(hù)接觸的類(lèi),用于取消毕贼、下載圖片等操作)
② AFImageDownloader.h / AFImageDownloader.m(真正實(shí)現(xiàn)取消温赔、下載圖片等操作)
③ AFAutoPurgingImageCache.h / AFAutoPurgingImageCache.m(該框架內(nèi)部實(shí)現(xiàn)的一個(gè)內(nèi)容緩存類(lèi))

3)公共接口

  • 由于各個(gè)文件的接口有很多,這里只列出部分重要的接口帅刀,剩余的接口可以參考源代碼:AFNetworking

① UIImageView+AFNetworking文件全部公共接口

/**
 *  用于設(shè)置AFImageDownloader下載器(用到了關(guān)聯(lián)對(duì)象)
 */
+ (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader;

/**
 *  用于獲取AFImageDownloader下載器(用到了關(guān)聯(lián)對(duì)象)
 */
+ (AFImageDownloader *)sharedImageDownloader;   

// 傳遞URL來(lái)設(shè)置UIImageView的圖片
- (void)setImageWithURL:(NSURL *)url;

// 傳遞URL設(shè)置UIImageView的圖片让腹,同時(shí),當(dāng)圖片沒(méi)有下載完時(shí)UIImageView只顯示占位圖   
- (void)setImageWithURL:(NSURL *)url
       placeholderImage:(nullable UIImage *)placeholderImage;

// 傳遞URL和占位圖扣溺,并且下載圖片成功或者失敗后有回調(diào)
- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
              placeholderImage:(nullable UIImage *)placeholderImage
                       success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
                       failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;  

// 取消下載的任務(wù) 
- (void)cancelImageDownloadTask;

② AFImageDownloader文件


// 獲取AFImageDownloader的單例對(duì)象    
+ (instancetype)defaultInstance;      

// 獲取默認(rèn)的NSURLCache  
+ (NSURLCache *)defaultURLCache;      

// 重新實(shí)現(xiàn)init方法  
- (instancetype)init;     

// 初始化AFHTTPSessionManager對(duì)象及其該分類(lèi)相關(guān)的屬性    
- (instancetype)initWithSessionManager (AFHTTPSessionManager *)sessionManager
                downloadPrioritization:(AFImageDownloadPrioritization)downloadPrioritization
                maximumActiveDownloads:(NSInteger)maximumActiveDownloads
                            imageCache:(nullable id <AFImageRequestCache>)imageCache;     

// 通過(guò)請(qǐng)求下載圖片    
- (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request
                                                        success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse  * _Nullable response, UIImage *responseObject))success
                                                        failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;    

// 通過(guò)請(qǐng)求下載圖片骇窍,同時(shí),指定了UUID   
- (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request
                                                 withReceiptID:(NSUUID *)receiptID
                                                        success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse  * _Nullable response, UIImage *responseObject))success
                                                        failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;    

// 取消下載操作        
- (void)cancelTaskForImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt;

③ AFAutoPurgingImageCache文件

// 該類(lèi)實(shí)現(xiàn)內(nèi)存緩存锥余,是通過(guò)NSDictionary來(lái)實(shí)現(xiàn)的

/**
  聲明了一系列將圖片放入緩存腹纳、從緩存移除圖片以及獲取緩存中圖片的API 
 */
@protocol AFImageCache <NSObject>

/**
    將圖片放入緩存identifier是字典的key值,用于存儲(chǔ)key對(duì)應(yīng)的UIImage
 */
- (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier;

/**
  通過(guò)identifier(也就是Key值)將對(duì)應(yīng)的的UIImage從緩存(字典)移除  
 */
- (BOOL)removeImageWithIdentifier:(NSString *)identifier;

/**
  很黃很暴力驱犹,一次性將緩存清空  
 */
- (BOOL)removeAllImages;

/**
  通過(guò)identifier獲取圖片
 */
- (nullable UIImage *)imageWithIdentifier:(NSString *)identifier;
@end

--- --
/**
   該協(xié)議是對(duì)AFImageCache的擴(kuò)充嘲恍,主要是將請(qǐng)求的URL和后面identifier替代之前AFImageCache之前的identifier。方法的內(nèi)部實(shí)現(xiàn)還是使用了AFImageCache的方法
 */
@protocol AFImageRequestCache <AFImageCache>

/**
  將圖片放入緩存
 */
- (void)addImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;

/**
  將圖片從緩存移除   
 */
- (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;

/**
  獲取圖片
 */
- (nullable UIImage *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;

@end

/**
   實(shí)現(xiàn)內(nèi)存緩存的具體類(lèi)
 */
@interface AFAutoPurgingImageCache : NSObject <AFImageRequestCache>

/**    
  初始化該緩存類(lèi)雄驹,默認(rèn)情況下memoryCapicty大小是100M佃牛,而圖片的緩存大小大于memoryCapicty時(shí),會(huì)清除圖片直到60M停止   
 */
- (instancetype)init;

/**
   一次性設(shè)置緩存的內(nèi)存大小
 ①  memoryCapacity :緩存區(qū)大小
 ② preferredMemoryCapaciry:圖片緩存超出緩存區(qū)大小后清除圖片后合適的剩余緩存大小
 */
- (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity;

@end

具體實(shí)現(xiàn)流程

  1. 當(dāng)我們想個(gè)ImageView的圖片進(jìn)行賦值時(shí)医舆,我們會(huì)調(diào)用以下代碼中的一種:

// 調(diào)用了②俘侠,占位圖片為空
① - (void)setImageWithURL:(NSURL *)url {
    [self setImageWithURL:url placeholderImage:nil];
}

//  調(diào)用了③ success和failure回調(diào)為nil         
② - (void)setImageWithURL:(NSURL *)url
       placeholderImage:(UIImage *)placeholderImage
{
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request addValue:@"image/*" forHTTPHeaderField:@"Accept"];

    [self setImageWithURLRequest:request placeholderImage:placeholderImage success:nil failure:nil];
}

// 最終實(shí)現(xiàn)地方
// 該方法思路:  
/**  
*  1) 判斷傳入的請(qǐng)求中URL是否為空;若為空蔬将,則取消下載爷速,imageView顯示占位圖片,否則霞怀,進(jìn)入下一步判斷          
*  2) 判斷當(dāng)前的請(qǐng)求是否有task處于活動(dòng)狀態(tài)(意思可能用戶(hù)單位時(shí)間內(nèi)多次發(fā)了同一個(gè)請(qǐng)求惫东,而在這個(gè)請(qǐng)求發(fā)送時(shí)已經(jīng)有下載的Task執(zhí)行了,這個(gè)請(qǐng)求將結(jié)束)                
*  3) 根據(jù)請(qǐng)求查看內(nèi)存緩存中是否目前有當(dāng)前請(qǐng)求的圖片毙石,若有則查看success有無(wú)回調(diào)廉沮,有回調(diào)則將圖片回調(diào)回去,否則徐矩,直接設(shè)置本ImageView的image    
*  4) 若本地內(nèi)存緩存沒(méi)有數(shù)據(jù)废封,則先將imageView的image設(shè)置為占位圖片并生成UUID,然后將請(qǐng)求和UUID發(fā)送出去; 若成功丧蘸,則檢查UUID是否和之前生成的UUID相等,以防止 
*  數(shù)據(jù)出錯(cuò),沒(méi)有問(wèn)題則根據(jù)success是否有回調(diào)將圖片發(fā)送出去;若失敗力喷,也檢查UUID是否相等刽漂,并根據(jù)有無(wú)failure回調(diào),將錯(cuò)誤信息輸出       
*
*/
③  - (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
              placeholderImage:(UIImage *)placeholderImage
                       success:(void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
                       failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure
{
    if ([urlRequest URL] == nil) {
        [self cancelImageDownloadTask];
        self.image = placeholderImage;
        return;
    }

    if ([self isActiveTaskURLEqualToURLRequest:urlRequest]){
        return;
    }

    [self cancelImageDownloadTask];
    AFImageDownloader *downloader = [[self class] sharedImageDownloader];
    id <AFImageRequestCache> imageCache = downloader.imageCache;

    //Use the image from the image cache if it exists
    UIImage *cachedImage = [imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil];
    if (cachedImage) {
        if (success) {
            success(urlRequest, nil, cachedImage);
        } else {
            self.image = cachedImage;
        }
        [self clearActiveDownloadInformation];
    } else {
        if (placeholderImage) {
            self.image = placeholderImage;
        }

        __weak __typeof(self)weakSelf = self;
        NSUUID *downloadID = [NSUUID UUID];
        AFImageDownloadReceipt *receipt;
        receipt = [downloader
                   downloadImageForURLRequest:urlRequest
                   withReceiptID:downloadID
                   success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull responseObject) {
                       __strong __typeof(weakSelf)strongSelf = weakSelf;
                       if ([strongSelf.af_activeImageDownloadReceipt.receiptID isEqual:downloadID]) {
                           if (success) {
                               success(request, response, responseObject);
                           } else if(responseObject) {
                               strongSelf.image = responseObject;
                           }
                           [strongSelf clearActiveDownloadInformation];
                       }

                   }
                   failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
                       __strong __typeof(weakSelf)strongSelf = weakSelf;
                        if ([strongSelf.af_activeImageDownloadReceipt.receiptID isEqual:downloadID]) {
                            if (failure) {
                                failure(request, response, error);
                            }
                            [strongSelf clearActiveDownloadInformation];
                        }
                   }];

        self.af_activeImageDownloadReceipt = receipt;
    }
}  


  1. 在1)中說(shuō)了弟孟,內(nèi)存緩存沒(méi)有使用請(qǐng)求和UUID去下載圖片贝咙,那么現(xiàn)在研究其下載操作

這段代碼有點(diǎn)長(zhǎng),耐心看一下

去下載圖片時(shí)的思路:

  1. 檢查請(qǐng)求的URL是否為空拂募,失敗則則返回信息(感覺(jué)這一句有點(diǎn)多余庭猩,因?yàn)檎{(diào)用這個(gè)方法之間已經(jīng)檢查了URL是否為空)
  2. 在Task沒(méi)有執(zhí)行時(shí),多個(gè)請(qǐng)求可能會(huì)同時(shí)達(dá)到該方法陈症,因此蔼水,需要一個(gè)字典存儲(chǔ)該URL對(duì)應(yīng)的AFImageDownloaderMergedTask,若有,則取出并創(chuàng)建一個(gè)AFImageDownloaderResponseHandler
    放入該自定義Task的一個(gè)響應(yīng)數(shù)組中录肯。并將該自定義task的NSURLSessionDataTask賦值給task;若沒(méi)有趴腋,則進(jìn)行下一步
  3. 由于對(duì)于磁盤(pán)緩存作者是使用NSURLCache進(jìn)行的,因此论咏,根據(jù)存儲(chǔ)策略進(jìn)行不同操作以便于下載圖片后進(jìn)行磁盤(pán)緩存
    4)之后就是從網(wǎng)絡(luò)下載圖片优炬,這也要注意,作者是使用AFN進(jìn)行異步下載的厅贪、會(huì)生成UUID和之前一樣去檢驗(yàn)下載后UUID是否發(fā)生改變蠢护;若成功,則將先緩存圖片养涮,然后將AFImageDownloaderMergedTask中數(shù)組所有響應(yīng)取出并將圖片等信息通過(guò)回調(diào)返回;若失敗葵硕,也一樣進(jìn)行回調(diào)錯(cuò)誤信息

注意:
1.作者默認(rèn)同時(shí)接受4個(gè)不同URL的請(qǐng)求,如果超過(guò)這個(gè)數(shù)量將把剩余的請(qǐng)求放入一個(gè)隊(duì)列中(使用數(shù)組實(shí)現(xiàn)的) 默認(rèn)是FIFO隊(duì)列单寂,也可以設(shè)置LIFO隊(duì)列
2.當(dāng)一個(gè)Task完成后都會(huì)檢查該隊(duì)列是否有剩余的Task贬芥,有則取出來(lái)并執(zhí)行


- (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request
                                                  withReceiptID:(nonnull NSUUID *)receiptID
                                                        success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse  * _Nullable response, UIImage *responseObject))success
                                                        failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure {
    __block NSURLSessionDataTask *task = nil;
    dispatch_sync(self.synchronizationQueue, ^{
        NSString *URLIdentifier = request.URL.absoluteString;
        if (URLIdentifier == nil) {
            if (failure) {
                NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorBadURL userInfo:nil];
                dispatch_async(dispatch_get_main_queue(), ^{
                    failure(request, nil, error);
                });
            }
            return;
        }

        // 1) Append the success and failure blocks to a pre-existing request if it already exists
        AFImageDownloaderMergedTask *existingMergedTask = self.mergedTasks[URLIdentifier];
        if (existingMergedTask != nil) {
            AFImageDownloaderResponseHandler *handler = [[AFImageDownloaderResponseHandler alloc] initWithUUID:receiptID success:success failure:failure];
            [existingMergedTask addResponseHandler:handler];
            task = existingMergedTask.task;
            return;
        }

        // 2) Attempt to load the image from the image cache if the cache policy allows it
        switch (request.cachePolicy) {
            case NSURLRequestUseProtocolCachePolicy:
            case NSURLRequestReturnCacheDataElseLoad:
            case NSURLRequestReturnCacheDataDontLoad: {
                UIImage *cachedImage = [self.imageCache imageforRequest:request withAdditionalIdentifier:nil];
                if (cachedImage != nil) {
                    if (success) {
                        dispatch_async(dispatch_get_main_queue(), ^{
                            success(request, nil, cachedImage);
                        });
                    }
                    return;
                }
                break;
            }
            default:
                break;
        }

        // 3) Create the request and set up authentication, validation and response serialization
        NSUUID *mergedTaskIdentifier = [NSUUID UUID];
        NSURLSessionDataTask *createdTask;
        __weak __typeof__(self) weakSelf = self;

        createdTask = [self.sessionManager
                       dataTaskWithRequest:request
                       uploadProgress:nil
                       downloadProgress:nil
                       completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                           dispatch_async(self.responseQueue, ^{
                               __strong __typeof__(weakSelf) strongSelf = weakSelf;
                               AFImageDownloaderMergedTask *mergedTask = self.mergedTasks[URLIdentifier];
                               if ([mergedTask.identifier isEqual:mergedTaskIdentifier]) {
                                   mergedTask = [strongSelf safelyRemoveMergedTaskWithURLIdentifier:URLIdentifier];
                                   if (error) {
                                       for (AFImageDownloaderResponseHandler *handler in mergedTask.responseHandlers) {
                                           if (handler.failureBlock) {
                                               dispatch_async(dispatch_get_main_queue(), ^{
                                                   handler.failureBlock(request, (NSHTTPURLResponse*)response, error);
                                               });
                                           }
                                       }
                                   } else {
                                       [strongSelf.imageCache addImage:responseObject forRequest:request withAdditionalIdentifier:nil];

                                       for (AFImageDownloaderResponseHandler *handler in mergedTask.responseHandlers) {
                                           if (handler.successBlock) {
                                               dispatch_async(dispatch_get_main_queue(), ^{
                                                   handler.successBlock(request, (NSHTTPURLResponse*)response, responseObject);
                                               });
                                           }
                                       }
                                       
                                   }
                               }
                               [strongSelf safelyDecrementActiveTaskCount];
                               [strongSelf safelyStartNextTaskIfNecessary];
                           });
                       }];

        // 4) Store the response handler for use when the request completes
        AFImageDownloaderResponseHandler *handler = [[AFImageDownloaderResponseHandler alloc] initWithUUID:receiptID
                                                                                                   success:success
                                                                                                   failure:failure];
        AFImageDownloaderMergedTask *mergedTask = [[AFImageDownloaderMergedTask alloc]
                                                   initWithURLIdentifier:URLIdentifier
                                                   identifier:mergedTaskIdentifier
                                                   task:createdTask];
        [mergedTask addResponseHandler:handler];
        self.mergedTasks[URLIdentifier] = mergedTask;

        // 5) Either start the request or enqueue it depending on the current active request count
        if ([self isActiveRequestCountBelowMaximumLimit]) {
            [self startMergedTask:mergedTask];
        } else {
            [self enqueueMergedTask:mergedTask];
        }

        task = mergedTask.task;
    });
    if (task) {
        return [[AFImageDownloadReceipt alloc] initWithReceiptID:receiptID task:task];
    } else {
        return nil;
    }
}   

  1. 正如之前所說(shuō),作者自定義一些類(lèi)如AFImageDownloadReceipt宣决、AFImageDownloaderResponseHandlerd等都是用來(lái)存儲(chǔ)信息的蘸劈,可以自行查看源代碼就會(huì)明白這些意思。這個(gè)代碼大致思路就是這個(gè)尊沸,還有取消下載威沫、開(kāi)始下載、還有AFHTTPSessionManager的配置可以查看源代碼進(jìn)行理解洼专。

4) 我要查看一下SDWebImage的UIImageView的源代碼棒掠,看看他們有什么不同。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末屁商,一起剝皮案震驚了整個(gè)濱河市烟很,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖雾袱,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恤筛,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡芹橡,警方通過(guò)查閱死者的電腦和手機(jī)毒坛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)林说,“玉大人煎殷,你說(shuō)我怎么就攤上這事⊥嚷幔” “怎么了豪直?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)度秘。 經(jīng)常有香客問(wèn)我顶伞,道長(zhǎng),這世上最難降的妖魔是什么剑梳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任唆貌,我火速辦了婚禮,結(jié)果婚禮上垢乙,老公的妹妹穿的比我還像新娘锨咙。我一直安慰自己,他們只是感情好追逮,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布酪刀。 她就那樣靜靜地躺著,像睡著了一般钮孵。 火紅的嫁衣襯著肌膚如雪骂倘。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天巴席,我揣著相機(jī)與錄音历涝,去河邊找鬼。 笑死漾唉,一個(gè)胖子當(dāng)著我的面吹牛荧库,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赵刑,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼分衫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了般此?” 一聲冷哼從身側(cè)響起蚪战,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤牵现,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后邀桑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體施籍,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年概漱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喜喂。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瓤摧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出玉吁,到底是詐尸還是另有隱情照弥,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布进副,位于F島的核電站这揣,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏影斑。R本人自食惡果不足惜给赞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望矫户。 院中可真熱鬧片迅,春花似錦、人聲如沸皆辽。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)驱闷。三九已至耻台,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間空另,已是汗流浹背盆耽。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓垫释,卻偏偏與公主長(zhǎng)得像嵌言,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子毛秘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,024評(píng)論 4 62
  • 寫(xiě)在開(kāi)頭: 大概回憶下氮昧,之前我們講了AFNetworking整個(gè)網(wǎng)絡(luò)請(qǐng)求的流程框杜,包括request的拼接,sess...
    涂耀輝閱讀 12,249評(píng)論 30 88
  • 哈哈哈袖肥,今天偷下懶咪辱,介紹一款小運(yùn)用天天打卡。它實(shí)用易用椎组,功能專(zhuān)注油狂,學(xué)習(xí)0成本。 使用這款運(yùn)用的起因是不想渾渾噩噩寸癌,...
    肥羅閱讀 622評(píng)論 0 0
  • 如果注定 如果注定能遇到相愛(ài)的人 我希望時(shí)間你能早點(diǎn)來(lái) 要不然 那炙熱的雙唇為誰(shuí)柔軟 那輕聲的耳語(yǔ)為誰(shuí)纏綿 那裹入...
    鮮衣怒馬_閱讀 164評(píng)論 0 1
  • 和同事一起吃食堂的時(shí)候蒸苇,突然聊起了愛(ài)情磷蛹。 大我五歲的姐姐說(shuō),她和現(xiàn)在的姐夫在一起挺不容易的溪烤,大學(xué)畢業(yè)女方家里不同意...
    文藝女青年專(zhuān)治各種不服閱讀 931評(píng)論 0 22