iOS - 如何在块分配变量后总是获取数据时控制块执行顺序?

时间:2016-05-26 09:20:07

标签: ios objective-c multithreading afnetworking block

我是iOS编程的新手,我很确定很多其他人都面临同样的问题。

问题是,我使用AFNetworking来处理我的http请求。

我正在尝试使用init方法获取一些数据,并且我想在ViewDidLoad()中为这些数据分配一个变量。

似乎AFNetworking发送了一个带有块**的get请求(可能是异步的但我尚未了解线程)**。

当我分配时,我想要获取的数据尚未返回。

我用谷歌搜索了

这样的答案

The execution of block is always delayed

block execution iOS and assigning variable

Variable returning null after block execution

但没有找到解决方案。

我想知道这是否是因为多线程机制,我该如何解决这个问题呢?

CODE

HomeController.m

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    NSInteger cateid = indexPath.row + 1;
    HomeTabCategoryController* categoryController = [[HomeTabCategoryController alloc] initWithCategoryId:cateid andCategoryName:[_categories objectForKey: [@(indexPath.row + 1) stringValue]]];
    [self.navigationController pushViewController:categoryController animated:YES];
}

CategoryController.m

-(instancetype)initWithCategoryId:(NSInteger)categoryId andCategoryName:(NSString*)categoryName{
    self = [super init];
    if (!self) {
        return nil;
    }
[ProductModel getProductsIdOfCategory:_categoryId success:^(BOOL result, NSString* message, NSArray* productIds){
        if (!result) {
            _productIds = productIds;
        }else{
            [self toast:message];
        }
    }failure:^(NSError* error){
        NSLog(@"%@", error);
    }];
    return self;
}

-(void)viewDidLoad{
    NSLog(@"loading view");
    [super viewDidLoad];
    self.title = _categoryName;

    [self getData];
}

- (void)getData{

for (NSNumber* proId in _productIds) {
    [ProductModel getProductWithId:[proId integerValue] success:^(BOOL result, NSString* message, ProductEntity* product){
        if (!result) {
            [_products addObject:product];
        }else{
            [self toast:message];
        }
    }failure:^(NSError* error){
        NSLog(@"%@", error);
    }];
}
}

执行getData时,_productIds仍然是nil(我在success区块中指定了它。)

2 个答案:

答案 0 :(得分:0)

当你有回复(productIds)&时,你不能像i-e呼叫那样叫你初始化方法吗?这很有道理。

> -(instancetype)initWithCategoryId:(NSInteger)categoryId andCategoryName:(NSString*)categoryName{
>     self = [super init];
>     if (!self) {
>         return nil;
>     } [ProductModel getProductsIdOfCategory:_categoryId success:^(BOOL result, NSString* message, NSArray* productIds){
>         if (!result) {
>             _productIds = productIds;
             **[self getData];**
>         }else{
>             [self toast:message];
>         }
>     }failure:^(NSError* error){
>         NSLog(@"%@", error);
>     }];
>     return self; }

答案 1 :(得分:0)

如果你想要它,一旦我从API调用得到响应而不是调用另一个API或方法。比使用下面的GCD串行队列

> dispatch_queue_t serialQueue =
> dispatch_queue_create("com.xyzapp.queue", DISPATCH_QUEUE_SERIAL);
>     
>     dispatch_async(serialQueue, ^{
> 
> [ProductModel getProductsIdOfCategory:_categoryId success:^(BOOL
> result, NSString* message, NSArray* productIds){
>         if (!result) {
>             _productIds = productIds;
>         }else{
>             [self toast:message];
>         }
>     }failure:^(NSError* error){
>         NSLog(@"%@", error);
>     }];
> 
>     });
>     
>     dispatch_async(serialQueue, ^{
>         
>         [self getData];
>     });