2016-05-26 5 views
0

私はiOSプログラミングが初めてで、多くの人が同じ問題に直面していると確信しています。iOS - 変数を割り当てた後にブロックが常にデータを取得するときのブロックの実行順序を制御する方法は?

問題は、httpリクエストを処理するのにAFNetworkingを使用しています。

私のinitメソッドでデータを取得しようとしていますが、これらのデータを持つ変数をViewDidLoad()に割り当てたいとします。

AFNetworkinggetリクエストをブロック**(おそらく非同期のものですが、私はまだスレッドについて学んでいません)**で送信しているようです。

私が割り当てているとき、私が得ようとしているデータはまだ戻っています。

私は

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ブロックに割り当てます)。

+0

あなたはいくつかの詳細を共有できますか? なぜINITに電話する必要がありますか? これはGCDシリアルキューで実現できると思います。 –

+0

これは 'HomeController'に' UITableView'があり、特定の行を選択すると新しいビューを表示したいからです。実際に私は前に 'GCD'について学んだことはありません。 'GCD'に問題があるなら、間違いなく文書を手に入れて使い方を学びます。しかし、問題は、私はまったく問題がないということでもありません。私はコードがどのように機能するかについてより詳しく知りたいと思っています。アドバイスをお願いしますか?ブロックにスレッドが作成されていますか?ブロックは実際にいつ実行されますか?少し早いですがお礼を。 :) –

答えて

0

応答(productIds)が&の場合、i-eコールのような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; } 
+0

はい、動作します。しかし、私はまだ内部のものを理解していない、これは将来同じ問題につながる可能性があります。ちょうどヒントをお願いしますか?私は自分自身の詳細についてはgoogleします。どうもありがとう! –

+0

親切に答えを受け入れます。それがあなたのために働くと、訪問者が利益を得ることができるように問題を解決します。 –

+0

いいえ、それはしません。理由は、ARRAYが満たされている場合にのみそのARRAYを使用しているメソッドを呼び出すことです。どのようにする必要がありますそう。 ブロックはASYNC呼び出しと同じです。あなたが応答を受け取ったときにのみ完了します。その配列が空だった理由は、ViewDidLoadがブロック応答の前に呼び出されていたことだけです。 –

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]; 
>  }); 
関連する問題