這幾天遇到一個(gè)bug沿量,相冊選擇圖片然后上傳伶选,最后回來的順序并不是你選擇圖片時(shí)的順序,于是想到了 在本地區(qū)處理這個(gè)東西干像。 當(dāng)然在這個(gè)問題解決后蛙埂,發(fā)現(xiàn)還有很多可供參考的解決辦法倦畅,比如:PromiseKit、NSOperationQueue绣的、以及AFNetworking 2中的batch request 也都可以解決這個(gè)問題叠赐。
-(void)pickMediaFromAlbum{
//TODO
__block PRImagePickerVc *vc = [PRImagePickerVc new];
vc.pickMode = kPickType_ImageOrVideo;
PDNavigationController *pvc = [[PDNavigationController alloc] initWithRootViewController:vc];
[self presentViewController:pvc animated:YES completion:nil];
__weak PRImagePickerVc *weakVc = vc;
__weak PRGroupChatVc *ws = self;
[vc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
[weakVc dismissViewControllerAnimated:YES completion:nil];
[photos enumerateObjectsUsingBlock:^(UIImage * _Nonnull image, NSUInteger idx, BOOL * _Nonnull stop) {
@autoreleasepool{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSString *path = [PDCommonUtil getPathByCompressImage:image ext:nil];
[dict setObject:[PDCommonUtil dictFromDimensions:image.size] forKey:path];
//單張上傳
[ws sendSingleFile:path dimensions:dict];
}
}];
}];
}
// ********************* 發(fā)送單張圖片 begin *********************
-(void)sendSingleFile:(NSString *)imageUrl dimensions:(NSDictionary *)dimensionDict{
if (imageUrl.length == 0) {
return;
}
//本地增加一個(gè)localID
NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithDictionary:@{@"localID" : @([UMSCloud getMessageID])}];
UMSMessageObject *msgo = [[UMSMessageObject alloc] initMessageWith:@"" peerID:_folderID.targetID.peerID attributes:attributes attachments:nil];
//發(fā)送單張圖片
[self sendSinglePicMsg:msgo path:imageUrl dimes:dimensionDict];
}
-(void)sendSinglePicMsg:(UMSMessageObject *)msgo path:(NSString *)filepath dimes:(NSDictionary *)dimesdict{
_bForceScrollToBottom = YES;
NSMutableArray *attachinfo = [NSMutableArray array];
BOOL ret = [[PDCvsMan shareInstance] saveMsgDraft:msgo at:self.folderID];
if (!ret) {
[[PDCvsMan shareInstance] notifySyncDataAdd:msgo folderID:self.folderID];
return;
}
__weak PRGroupChatVc *ws = self;
[[PDCvsMan shareInstance] saveAttachsDraft:@[filepath] desc:nil dimens:dimesdict at:msgo.attributes[@"localID"]];
[msgo ums_setAttachments:@[]];
NSURL *url;
if ([[filepath lowercaseString] hasPrefix:@"file:"]) {
url = [NSURL URLWithString:filepath];
}else{
url = [NSURL fileURLWithPath:filepath];
}
NSString *filePath = url.path;//[obj substringFromIndex:@"file://".length];
NSString *contentType = [PDCommonUtil mimeTypeForExtension:filePath.pathExtension];
NSFileManager *fm = [NSFileManager defaultManager];
NSDictionary *fileAttr = [fm attributesOfItemAtPath:filePath error:nil];
UInt64 fsize = [fileAttr fileSize];
SInt64 msgId = [UMSCloud getMessageID];
UMSFileAttachment *fattach = [[UMSFileAttachment alloc] initWithFileUrl:@"" thumb:nil contentType:[UMSCloudContentType valueOf:contentType] fileSize:fsize fname:filePath.lastPathComponent];
NSMutableDictionary *attr = [NSMutableDictionary dictionaryWithDictionary:@{@"fid": @(msgId).description}];
NSDictionary *dimens = dimesdict[filepath];
if (dimens) {
attr[@"dimensions"] = dimens;
}
attr[@"localimg"] = [UIImage imageWithContentsOfFile:filePath];
UMSAttachment *attach = [[UMSAttachment alloc] initWith:UMSProtoAttachmentTypeAttachmentTypeFile text:@"" fallback:@"" attributes:attr];
[attach setAttachmentBody:fattach];
[msgo addAttachments:@[attach.dictValue]];
//創(chuàng)造一個(gè)信號量 用于將異步的上傳改造成同步的
if (!semaphore) {
semaphore = dispatch_semaphore_create(0);
}
if (!queue) {
queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
}
//加一個(gè)這個(gè) 其實(shí)是擔(dān)心內(nèi)存上漲
@autoreleasepool{
dispatch_async(queue, ^{
[[UMSCloud shareInstance] uploadFileWithPath:filePath public:YES progress:^(UMSFileProgress *resp) {
} response:^(UMSUploadFileResponse *resp) {
if (!resp.isSuccess) {
msgo.sendStates = KMsgSendFail;
[[PDCvsMan shareInstance] notifySyncDataUpdate:msgo folderID:ws.folderID];
return ;
}
//信號加1
dispatch_semaphore_signal(semaphore);
UMSFileAttachment *fattach = [[UMSFileAttachment alloc] initWithFileUrl:resp.fileUrl thumb:resp.thumbUrl contentType:[UMSCloudContentType valueOf:contentType] fileSize:resp.fileSize fname:filePath.lastPathComponent];
attr[@"localimg"] = @"";
UMSAttachment *attach = [[UMSAttachment alloc] initWith:UMSProtoAttachmentTypeAttachmentTypeFile text:@"" fallback:@"" attributes:attr];
[attach setAttachmentBody:fattach];
[attachinfo addObject:attach.dictValue];
NSString *path = [PDCommonUtil getDownloadFilePathby:attach];
[[NSFileManager defaultManager] copyItemAtURL:url toURL:[NSURL fileURLWithPath:path] error:nil];
[msgo setRelpyID:@""];
[msgo ums_setAttachments:attachinfo];
[[PDCvsMan shareInstance] updateMsgsDraft:msgo at:_folderID];
[[PDCvsMan shareInstance] removeAttachsDraft:msgo.attributes[@"localID"]];
[[PDCvsMan shareInstance] sendMessage:msgo at:_folderID];
NSURL *url = [NSURL URLWithString:filepath];
[[NSFileManager defaultManager] removeItemAtURL:url error:nil];
}];
//信號減1
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
}
[[PDCvsMan shareInstance] notifySyncDataAdd:msgo folderID:self.folderID];
}
// ********************* 發(fā)送單張圖片 end *********************
網(wǎng)上看到一段對信號量的 解釋 很有意思:
停車場剩余4個(gè)車位,那么即使同時(shí)來了四輛車也能停的下屡江。如果此時(shí)來了五輛車燎悍,那么就有一輛需要等待。
信號量的值就相當(dāng)于剩余車位的數(shù)目盼理,dispatch_semaphore_wait函數(shù)就相當(dāng)于來了一輛車谈山,dispatch_semaphore_signal
就相當(dāng)于走了一輛車。停車位的剩余數(shù)目在初始化的時(shí)候就已經(jīng)指明了(dispatch_semaphore_create(long value))宏怔,
調(diào)用一次dispatch_semaphore_signal奏路,剩余的車位就增加一個(gè);調(diào)用一次dispatch_semaphore_wait剩余車位就減少一個(gè)臊诊;
當(dāng)剩余車位為0時(shí)鸽粉,再來車(即調(diào)用dispatch_semaphore_wait)就只能等待。有可能同時(shí)有幾輛車等待一個(gè)停車位抓艳。