我从两个视图控制器运行两个AFJSONRequestOperation
,它们被一个接一个地调用:
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:
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.."];
问题是显示的状态仅适用于第二个操作:Loading categories..
尽管他们完成了网络连接并获得了JSON结果。
似乎我不能使用NSOperationQueue
,因为这两个操作都在分开的控制器中。那么如何确保一个人等到第一个完成后向用户显示两个状态消息?
答案 0 :(得分:1)
有几点想法:
如果你真的想要,你肯定可以为这两个操作使用相同的操作队列。您可以将操作队列从第一个控制器传递到第二个控制器。或者你可以为你的队列设置一个单例类。
但这是一个有争议的问题,因为您还可以在完成第一个操作时建立第二个操作的依赖关系,而无需使用共享队列。您只需要将第一个请求的NSOperation
传递给第二个控制器,然后将第一个操作设置为第二个操作dependency
。
然而,这也是一个有争议的问题,因为如果你不需要,你为什么要引入串行操作的人为约束。如果同时运行它们而不是按顺序运行,则两个网络操作可以大大加快运行速度为了简化您更新HUD的工作量,以较慢的性能惩罚用户似乎是一种耻辱。
在我看来,正确的解决方案是支持并发操作并适当更新HUD。也许维护一组可变的状态消息,您可以在列表中添加和删除它们。
也许是这样的:
@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