如何在包含AFHTTPRequestOperationManager的方法完成其工作时通知?

时间:2013-11-12 08:23:31

标签: grand-central-dispatch afnetworking-2 afhttprequestoperation

我有一个使用AFHTTPRequestOperationManager POST来检索json脸部特征的方法:

+(Face *)getFace:(UIImage *) image
{
    __block Face *face = [[Face alloc]init];

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    NSDictionary *parameters = @{@"selector": @"FULL"};

    NSData *imageData = UIImagePNGRepresentation(image);

    [manager POST:@"http://api.animetrics.com/v1/detect" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileData: imageData name:@"image" fileName:[NSString stringWithFormat:@"file%d.png",1] mimeType:@"image/png"];
    } success:^(AFHTTPRequestOperation *operation, id responseObject) {

        NSError* error;

        face = [[Face alloc] initWithString:responseObject error:&error];

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];

    return face;
}

我在视图控制器中使用GCD调用了此方法:

dispatch_queue_t queue = dispatch_queue_create("My Queue",NULL);

dispatch_async(queue, ^{

    Face *face = [Face getFace:[UIImage imageNamed:@"image.png"]];

    dispatch_async(dispatch_get_main_queue(), ^{

        [face getPoints];

    });
});

问题是[face getPoints]始终返回null,因为它在getFace方法完成检索json对象之前执行。我认为那是因为AFNetworking本身正在使用GCD。但是我该如何解决这个问题呢?我错过了什么? 我使用的是最新的AFNetworking 2.0。

1 个答案:

答案 0 :(得分:0)

你可以用“延续传递风格”来做到这一点。它可能看起来像这样:

+ (void)getFace:(UIImage *) image completion: (void (^)(Face* theFace, BOOL success, NSError* error))completion
{
    if (!completion)
        return; // If you don't care about the result, why should we do anything?

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    NSDictionary *parameters = @{@"selector": @"FULL"};

    NSData *imageData = UIImagePNGRepresentation(image);

    [manager POST:@"http://api.animetrics.com/v1/detect" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileData: imageData name:@"image" fileName:[NSString stringWithFormat:@"file%d.png",1] mimeType:@"image/png"];
    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSError* error = nil;
        Face* face = [[Face alloc] initWithString:responseObject error:&error];
        completion(face, nil != face, error);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        completion(nil, NO, error);
    }];
}

然后使用它,你会这样做:

dispatch_async(dispatch_get_global_queue(0, 0), ^{
    [[self class] getFace: [UIImage imageNamed:@"image.png"] completion:^(Face* theFace, BOOL success, NSError* error) {

        if (success)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                [theFace getPoints];
            });
        }
        else
        {
            NSLog(@"error: %@", error);
        }
    });
});