2

私はiOSでブロックを使用するのが初めてで、おそらくそれが私の問題の核心だと考えています.

Restful サービスからデータをフェッチするだけの単純な静的 DataManager クラスを構築したいだけです。

さまざまな UIViewControllers (または collectionview/table コントローラー) からこれを呼び出します。

私のクラスでは、このような関数があります

+ (NSArray *) SearchByKeyword: (NSString*) keyword {
    __block NSArray* searchResults = [[NSArray alloc] init];
    NSString *baseURL = @"http://someURL.com/api/search";
    NSString *requestURL = [baseURL stringByAppendingString:keyword];
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:baseURL]];
    NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET"
                                                      path:requestURL
                                                      parameters:nil];
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        searchResults = [JSON valueForKeyPath:@""];
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
    }];
    [operation start];
    return searchResults;
}

ただし、これはゼロデータを返し続けます。誰かがこれを行う正しい方法を提案できますか?

4

2 に答える 2

7

非同期タスク (JSON 操作) の結果を同期メソッド呼び出しの戻り値として使用しようとしているため、データが取得されません。

AFネットワーキングのものと同様に、完了ブロックと失敗ブロックを受け取るAPIをView Controllerに提供できます。ビュー コントローラーは、結果がブロックに渡されたときに、必要な処理を行うことができます。

質問からコードを変更する:

typedef void (^SearchCompletionBlock)(NSArray *results);
typedef void (^SearchFailureBlock)(NSError *error);

+ (void)searchByKeyword:(NSString*)keyword completionBlock:(SearchCompletionBlock)completionBlock failureBlock:(SearchFailureBlock)failureBlock;
{
    NSString *baseURL = @"http://someURL.com/api/search";
    NSString *requestURL = [baseURL stringByAppendingString:keyword];
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:baseURL]];
    NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET"
                                                            path:requestURL
                                                      parameters:nil];
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
                                                                                        success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
                                                                                            if (completionBlock) {
                                                                                                completionBlockc([JSON valueForKeyPath:@""]);
                                                                                            }
                                                                                        } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
                                                                                            NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
                                                                                            if (failureBlock) {
                                                                                                failureBlock(error);
                                                                                            }
                                                                                        }];
    [operation start];
}

その後、クライアントは、結果を保存してビューをリロードする完了ブロックを渡すことができます。何かのようなもの:

^ (NSArray *results) {
    self.results = results;
    [self.tableView reloadData];
}
于 2013-03-01T06:58:31.677 に答える
1

JSON 要求操作は非同期です。つまり、要求を開始し ( [operations start]、その後すぐに結果を返します。結果は空になります。完了ブロックが実行されると、データが割り当てられますが、何も行われません。検索メソッドは次のことができます。 t は、リクエストが完了するまで待機しない限り、オブジェクトを返しません。

いくつかのオプションがあります:

  1. 結果を処理する検索メソッドに完了ブロックを渡します。完了ブロックは、すべてのサービス固有のもの (JSON の処理など) が完了すると、要求の完了ブロックで呼び出されます。(ブロックインセプション!)

  2. 要求の完了ブロックでデータ マネージャーのプロパティを割り当て、デリゲート メソッドまたは通知を呼び出して、結果が利用可能であることを他のユーザーに知らせます。

私はオプション1を好むでしょう。

于 2013-03-01T06:53:11.627 に答える