iOS-AFNetworking3.0上傳大量(1000張)圖片到伺服器

來源:互聯網
上載者:User

標籤:file   use   pool   blank   ddd   add   著作權   get   release   

背景:

最近項目要做上傳圖片功能,圖片必須是高清的,所以不讓壓縮,上傳圖片是大量的,比如幾百張,這個如果是用afn,將圖片直接for迴圈加入到formData裡會出現一個問題,臨時變數太多,導致記憶體緊張,最後程式奔潰。之前寫過用自動釋放池解決它,但是還是效果不大。如果上傳的多的話,記憶體還是受不了。

解決辦法一適用於圖片少量的如40張圖片

我之前寫的在這,可以看看自動釋放池的方法,如果你上傳圖片的數量不多的話,可以用這種方法。也很簡單的。連結在這裡http://www.jianshu.com/p/9e84fe63d5c0

解決辦法二適用於圖片大量的如1000張圖片

思考,為甚記憶體會佔用那麼多呢?就是因為圖片一口氣讀到記憶體中了。如果咱們上傳三五張圖片,肯定不會出問題。如何把1000張圖片分開傳呢?所以必須要用到多線程的知識。建立個隊列。然後挨個傳。注意不要把檔案存到隊列裡,只要先存一個檔案名稱,執行的時候再去讀取檔案的內容。如果要是將image傳給隊列,記憶體還是會爆的。所以存個圖片名字。一個字串肯定沒有image佔用的記憶體大吧。上代碼吧。我的圖片來源於相簿,所以我用的圖片id。

/** 建立隊列然後開始上傳圖片 @param LocalIdArray 擷取相簿的圖片id數組,如果你是本地的就傳遞圖片名字數組,或者是沙箱的檔案名稱字數組 */- (void)uploadOperation:(NSArray *)LocalIdArray{        NSOperationQueue *queue = [[NSOperationQueue alloc]init];    self.queue = queue;    //這個就是控制同時上傳幾張圖片的,如果是1的話就是串列隊列了。我是4,是並行隊列。    queue.maxConcurrentOperationCount = 4;            for (int i = 0; i<LocalIdArray.count; i++)    {        //加上自動釋放池,及時的釋放臨時變數,防止記憶體奔潰        @autoreleasepool {                        NSString *imageName = [NSString stringWithFormat:@"up_%d.jpg",i];                        WS(weakSelf)            //建立一個任務            NSBlockOperation *uploadOperation = [NSBlockOperation blockOperationWithBlock:^{                                [weakSelf uploadTaskWithLocalId:LocalIdArray[i] imageount:LocalIdArray.count imageName:imageName];            }];            //將任務加入到隊列中            [queue addOperation:uploadOperation];        }            }        }/** 開始上傳單張圖片 @param LocalId 圖片的id @param count 一共上傳多少張圖片 @param imageName 圖片的名稱 */- (void)uploadTaskWithLocalId:(NSString *)LocalId imageount:(NSInteger)count imageName:(NSString *)imageName{        //通過圖片的id轉化為image,如果是圖片名字或者是沙箱圖片檔案名稱字那更簡單了。    CustomAlbumTool *customAlbumTool = [CustomAlbumTool sharedCustomAlbumTool];    PHFetchResult<PHAsset *> *upAssetArr = [PHAsset fetchAssetsWithLocalIdentifiers:@[LocalId] options:nil];    PHAsset *asset = [upAssetArr firstObject];    UIImage *image = [customAlbumTool getImageWithAsset:asset targetSize:PHImageManagerMaximumSize];        //afn上傳的參數    NSMutableDictionary *dic = [NSMutableDictionary dictionary];    dic[@"xxx"] = [UserDataCenter xxx];    dic[@"xxx"] = self.xxx;        //因為afn上傳是非同步執行的所以建立一個訊號量。就是為了讓一個任務完全的執行完畢後才執行下一個任務。加訊號量就是為了把afn非同步轉化為同步。如果不轉化的話。queue.maxConcurrentOperationCount = 1,也沒辦法做到隊列內同步。    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);            WS(weakSelf)    [SWAYNetWorking uploadWithUrl:uploadModelUrl parameters:dic constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {                NSData *data = UIImageJPEGRepresentation(image, 1.0);        [formData appendPartWithFileData:data name:@"file" fileName:imageName mimeType:@"image/jpeg"];            } withProgress:^(NSProgress *uploadProgress) {            } success:^(id responseObject) {                //圖片成功了讓訊號量加1        dispatch_semaphore_signal(semaphore);            } failure:^(NSError *error) {                //圖片傳失敗了讓訊號量加1        dispatch_semaphore_signal(semaphore);            }];        //訊號量等待。DISPATCH_TIME_FOREVER 永遠等到吧。    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);        }
監聽全部成功重新整理ui,可以定義個int型變數,上傳成功一張圖片加1。如果等於總的圖片數量就相當於上傳完成了,那麼就重新整理UI吧。也可以建立個上傳成功重新整理UI的任務。添加依賴。在任務裡執行重新整理UI。
/** 建立隊列然後開始上傳圖片 @param LocalIdArray 擷取相簿的圖片id數組,如果你是本地的就傳遞圖片名字數組,或者是沙箱的檔案名稱字數組 */- (void)uploadOperation:(NSArray *)LocalIdArray{    NSOperationQueue *queue = [[NSOperationQueue alloc]init];    self.queue = queue;    //這個就是控制同時上傳幾張圖片的,如果是1的話就是串列隊列了。我是4,是並行隊列。    queue.maxConcurrentOperationCount = 4;    NSBlockOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{        [[NSOperationQueue mainQueue] addOperationWithBlock:^{ // 回到主線程執行,方便更新 UI 等                  }];    }];    for (int i = 0; i<LocalIdArray.count; i++)    {        //加上自動釋放池,及時的釋放臨時變數,防止記憶體奔潰        @autoreleasepool {            NSString *imageName = [NSString stringWithFormat:@"up_%d.jpg",i];            WS(weakSelf)            //建立一個任務            NSBlockOperation *uploadOperation = [NSBlockOperation blockOperationWithBlock:^{                [weakSelf uploadTaskWithLocalId:LocalIdArray[i] imageount:LocalIdArray.count imageName:imageName];            }];           //添加依賴。            [completionOperation addDependency:uploadOperation];            //將任務加入到隊列中            [queue addOperation:uploadOperation];        }    }     //將重新整理UI的任務排入佇列,當所有的上傳任務結束才會調用completionOperation。     [queue addOperation:completionOperation];}
如果要是你的業務是不能讓一張圖片傳遞失敗,那麼當有一張圖沒有傳成功的話就直接取消所有任務就行了。
[weakSelf.queue cancelAllOperations];


王銀博
連結:http://www.jianshu.com/p/5162df747879
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

iOS-AFNetworking3.0上傳大量(1000張)圖片到伺服器

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.