我用一个for循环上传三张照片(用的是afnetworking框架)。
上传它就开了一个线程,上传成功后后台返回一个filename,把filename放进一个数组
我想等三张照片全都上传结束后,对获取到的三个filename进行操作
要怎么做?
NSMutableArray *fileNameArr = [[NSMutableArray alloc]init];
for (int i= 0; i<[self.imgArr count]; i++) {
NSData *data = [self.imgArr objectAtIndex:i];
[manager POST:url parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData){
[formData appendPartWithFileData:data name:@"pic" fileName:fileName mimeType:@"image/jpeg"];
}success:^(AFHTTPRequestOperation *operation,id responseObject){
NSLog(@"success:%@",responseObject);
NSString *str = [[responseObject objectForKey:@"data"] objectForKey:@"fileName"];
[fileNameArr addObject:str];
NSString *ids = [[responseObject objectForKey: @"data"] objectForKey:@"ids"];
}
failure:^(AFHTTPRequestOperation *operation,NSError *error){
NSLog(@"%@",error);
}];
}
简单点设置一个变量,等加到3了,再处理
观察者模式。主线程监听子线程执行情况,子线程执行完毕,调用监听器方法即可。
用Notification写好了。在三个任务都完成之后发送通知,然后执行注册的方法。
第一种是Notification,这个比较解耦。
-(void)viewDidLoad
{
// add a notification observer
[NSNotificationCenter defaultCenter] addObserver:selector:name:object:]
}
-(void)handle
{
if (fileNameArr.count == 3) {
// do something
}
}
NSMutableArray *fileNameArr = [[NSMutableArray alloc]init];
for (int i= 0; i<[self.imgArr count]; i++) {
NSData *data = [self.imgArr objectAtIndex:i];
[manager POST:url
parameters:nil
constructingBodyWithBlock:
^(id<AFMultipartFormData> formData){
[formData appendPartWithFileData:data
name:@"pic"
fileName:fileName
mimeType:@"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation,id responseObject) {
NSLog(@"success:%@",responseObject);
NSString *str = [[responseObject objectForKey:@"data"] objectForKey:@"fileName"];
[fileNameArr addObject:str];
NSString *ids = [[responseObject objectForKey: @"data"] objectForKey:@"ids"];
// add here
[NSNotificationCenter defaultCenter] postNotificationName:object:]
} failure:^(AFHTTPRequestOperation *operation,NSError *error){
NSLog(@"%@",error);
}];
}
第二种就是,GCD啦,但是代码看起来耦合比较高。
NSMutableArray *fileNameArr = [[NSMutableArray alloc]init];
for (int i= 0; i<[self.imgArr count]; i++) {
NSData *data = [self.imgArr objectAtIndex:i];
[manager POST:url
parameters:nil
constructingBodyWithBlock:
^(id<AFMultipartFormData> formData){
[formData appendPartWithFileData:data
name:@"pic"
fileName:fileName
mimeType:@"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation,id responseObject){
NSLog(@"success:%@",responseObject);
NSString *str = [[responseObject objectForKey:@"data"] objectForKey:@"fileName"];
[fileNameArr addObject:str];
NSString *ids = [[responseObject objectForKey: @"data"] objectForKey:@"ids"];
// here
if (fileNameArr.count == 3) {
dispatch_async(dispatch_get_main_queue(), ^{
// handle
});
}
} failure:^(AFHTTPRequestOperation *operation,NSError *error){
NSLog(@"%@",error);
}];
}
没仔细看你为什么要回到主线程哈,要回的话这样就可以啦:
dispatch_sync(dispatch_get_main_queue(), ^(){
// 这里的代码会在主线程执行
});
上面的两个答案应该不是题主想要的,上传图片是异步的,但是要等三个全部上传完成才做下一步操作,这是要求同步。通知可以,但GCD可以更方便,用dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了,符合你的要求,还可以用信号量来处理,不过这有些老了