1

私はチュートリアルからいくつかのコードを試してみましたが、GCD について理解していないためにあまり成功していません。

API.m という名前のクラスがあり、GCD に関するコードは次のとおりです。

+ (API *) sharedInstance
{
    static API *sharedInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        sharedInstance = [[self alloc] initWithBaseURL:[NSURL URLWithString:APIHost]];
    });

    return sharedInstance;
}

-(void)commandWithParams:(NSMutableDictionary*)params
            onCompletion:(JSONResponseBlock)completionBlock
{
    NSMutableURLRequest *apiRequest = [self multipartFormRequestWithMethod:@"POST"
                                                                      path:APIPath
                                                                parameters:params
                                                 constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
                                                     //TODO: attach file if needed
                                                 }];

    AFJSONRequestOperation* operation = [[AFJSONRequestOperation alloc] initWithRequest: apiRequest];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        //success!
        completionBlock(responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        //failure :(
        completionBlock([NSDictionary dictionaryWithObject:[error localizedDescription] forKey:@"error"]);
    }];

    [operation start];
}

ボタンを実装し、NSArray を取得してその内容を出力ウィンドウに出力することで、簡単なテストを行います。

- (IBAction)test:(id)sender {

    NSMutableDictionary* params =[NSMutableDictionary dictionaryWithObjectsAndKeys:
                                  @"pending", @"command",
                                  [[[API sharedInstance] user] objectForKey:@"UserID"] , @"userID",
                                  nil];

    [[API sharedInstance] commandWithParams:params
                               onCompletion:^(NSDictionary *json) {
                                   //result returned

                                   if ([json objectForKey:@"error"]==nil) {
                                       // Simple example
                                       [self.users addObject:@"1"];

                                   } else {
                                       //error
                                       [UIAlertView title:@"Error" withMessage:[json objectForKey:@"error"]];
                                   }

                               }];
    NSLog(@"%@", self.users);
}

ボタンを最初にクリックすると、空の NSArray が出力ウィンドウに出力されますが、もう一度押すと「1」が出力されます。完了ブロックが完全に実行される前に、プログラムが NSLog に到達していることは明らかです。完了ブロックが終了した後に NSLog を実行するオプションがあるように、誰かがコードを変更するのを手伝ってくれませんか?

4

1 に答える 1

1

何を達成しようとしているのかはわかりませんが、目標が完了ブロックの後に NSLog を実行することだけである場合は、NSLog ステートメントを後に移動できます。

[self.users addObject:@"1"];

配列に追加した後に実行したいコードがある場合は、

[self methodName]; in the completion block and it will get called there.

完了ブロックは、実行したいコードの実行後に実行されるコードです。実行したいコードは、非同期で別のスレッドで実行されます。そのコードが実行された後、完了ブロック コードが実行されます。

于 2012-11-06T15:46:41.227 に答える