[英]how to manage concurrently two AFNetworking operations from two different controllers
I am running two AFJSONRequestOperation
from two view controllers, they gets called one right after the other: 我正在从两个视图控制器运行两个
AFJSONRequestOperation
,它们在另一个之后立即被调用:
viewcontroller1: viewcontroller1:
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON){
//
}failure:^(NSURLRequest *request, NSHTTPURLResponse *response,NSError *error, id JSON){
//
}];
[operation start];
[SVProgressHUD showWithStatus:@"Searching for products, please wait.."];
viewcontroller2: viewcontroller2:
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON){
//
}failure:^(NSURLRequest *request, NSHTTPURLResponse *response,NSError *error, id JSON){
//
}];
[operation start];
[SVProgressHUD showWithStatus:@"Loading categories.."];
The problem is that the status shown is only for the second operation: Loading categories..
although they completed both networking and getting JSON results just fine. 问题在于,显示的状态仅适用于第二项操作:
Loading categories..
尽管它们完成了联网并获得JSON结果都很好。
It seems I cannot use NSOperationQueue
since the two operations are in separated controllers. 似乎我不能使用
NSOperationQueue
因为这两个操作位于单独的控制器中。 So how to make sure one wait until the first is done to show both status messages to user? 那么如何确保等到第一个完成后再向用户显示两个状态消息呢?
A couple of thoughts: 一些想法:
You certainly could use the same operation queue for the two operations if you really wanted. 如果确实需要,您当然可以对两个操作使用相同的操作队列。 You'd either pass the operation queue from the first controller to the second one.
您可以将操作队列从第一个控制器传递到第二个控制器。 Or you could have a singleton class for your queue.
或者您可以为队列设置一个单例类。
That's a moot point, though, because you can also establish a dependency of the second operation upon the completion of the first operation without using a shared queue. 不过,这是有争议的,因为您还可以在完成第一个操作时就建立第二个操作的依赖关系,而无需使用共享队列。 You'd just need to pass the
NSOperation
for the first request from the first controller to the second one, and then you set that first operation to be a dependency
for the second one. 您只需
NSOperation
第一个请求的NSOperation
传递给第二个控制器,然后将第一个操作设置为第二个控制器的dependency
。
That, too, is a moot point, though, because why would you want to introduce an artificial constraint of serial operation if you don't have to. 不过,这也是有争议的,因为您为什么要在不需要的情况下引入人为的串行操作约束。 Two network operations can run considerably faster if you run them concurrently rather than sequentially.
如果同时运行而不是顺序运行,则两个网络操作的运行速度将大大提高。 It seems like a shame to punish the user with slower performance for the sake of simplifying your effort to update the HUD.
为了简化更新HUD的工作,以较慢的性能惩罚用户似乎很可耻。
The right solution, in my opinion, would be to support concurrent operations and update the HUD appropriately. 我认为正确的解决方案是支持并发操作并适当更新HUD。 Perhaps maintain a mutable array of status messages that you can add and remove from the list.
也许维护一个可变的状态消息数组,您可以在列表中添加和删除它们。
Perhaps something like: 也许像这样:
@interface HUDStatus ()
@property (nonatomic, strong) NSMutableArray *statusMessages;
@end
@implementation HUDStatus
+ (instancetype)sharedHudManager
{
static id sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init
{
self = [super init];
if (self) {
_statusMessages = [[NSMutableArray alloc] init];
}
return self;
}
- (void)addMessage:(NSString *)message
{
[self.statusMessages addObject:message];
[SVProgressHUD showWithStatus:message];
}
- (void)removeMessage:(NSString *)message
{
__block BOOL didFindMessage = NO;
// remove the message (not sure which one it is, so we'll look through all of them
[self.statusMessages enumerateObjectsWithOptions:0 usingBlock:^(NSString *oldMessage, NSUInteger idx, BOOL *stop) {
if ([oldMessage isEqualToString:message])
{
[self.statusMessages removeObjectAtIndex:idx];
didFindMessage = YES;
*stop = YES;
}
}];
if (!didFindMessage)
NSLog(@"%s: Trying to remove '%@' but it was not found in %@", __FUNCTION__, message, self.statusMessages);
// if, having removed
if ([self.statusMessages count] > 0)
[SVProgressHUD showWithStatus:[self.statusMessages lastObject]];
else
[SVProgressHUD dismiss]; // I don't know this class, so I don't know what the name of the method to dismiss the HUD
}
@end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.