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

iOS - How to control block execution order when the block always get data after assigning variables?

我是 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

但没有找到解决方案。

请问是不是多线程机制的问题,如何解决?


代码

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块)

当你有响应 (productIds) 并且它有意义时,你不能像 i-e call 那样调用你的 init 方法吗?

> -(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; }

如果您想要它,一旦我收到 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];
>     });