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

Not sure as to what you are trying to accomplish, but if the goal is to just have NSLog execute after the completion block, you can move the NSLog statement after

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

If you have some code which you want to execute after adding it to the array, you can have

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

Completion block, is the code which is run after execution of the code which you wanted run. The code which you wanted run, will happen asynchronously and on another thread. After that code is run, the completion block code will get executed.

于 2012-11-06T15:46:41.227 回答