AFNetworking完成块等到完成

时间:2014-03-06 22:14:49

标签: ios objective-c multithreading afnetworking afnetworking-2

我正在使用AFNetworking进行POST请求。我需要等到完成块完成才能返回数据,我遇到了问题。

我有一个解决方案,直到我切换到AFNetworking:

int i = 0;

while (!done)
{
    [NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
    i++;

    NSLog(@"While Loop:%i", i);

    if (i == 149) //request timed out
        done = YES;
}

现在,该解决方案偶尔会起作用。有时它只在NSLog(@"While Loop:%i", i);仅记录1或2时完成,但有时它会记录到149并超时。似乎NSRunLoop有时会在不同的线程中运行,但有时会在阻止我请求的同一线程上运行。

以下是我目前的代码:

- (id)postRequestWithBaseURLString:(NSString *)baseURLString function:(NSString *)function parameters:(NSDictionary *)parameters
{
    if (baseURLString)
        function = [baseURLString stringByAppendingString:function];

    __block BOOL done = NO;
    __block id returnObject = nil;

    [self.manager POST:function parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject)
     {
         NSLog(@"Success: %@", responseObject);

         done = YES;
         returnObject = responseObject;
     }

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

    [manager.operationQueue waitUntilAllOperationsAreFinished];

    int i = 0;

    while (!done)
    {
        [NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
        i++;

        NSLog(@"While Loop:%i", i);

        if (i == 149) //request timed out
            done = YES;
    }

    return returnObject;
}

我尝试过dispatch_group但没有成功。帮助

修改

好的,我有更多信息。当我第一次调用API时(例如,当我第一次调用ViewController时),我的解决方案有效,但之后没有。也许,在加载视图之后,在与API调用相同的线程上调用while循环,从而阻塞它?

这似乎也很可能,因为在超时发生后几乎完全调用NSLog(@"Success: %@", responseObject);

1 个答案:

答案 0 :(得分:5)

在线找到优雅的解决方案。我创建了自己的完成块。这是我做的:

+ (void)jsonRequestWithBaseURL:(NSString *)baseURL function:(NSString *)function parameters:(NSDictionary *)parameters completion:(void (^)(NSDictionary *json, BOOL success))completion
{
    if (baseURL)
        function = [baseURL stringByAppendingString:function];

    NSLog(@"%@ function:%@, parameters:%@", self.class, function, parameters);

    [AFHTTPRequestOperationManager.manager POST:function parameters:parameters success:^(AFHTTPRequestOperation *operation, id jsonObject)
     {
         //NSLog(@"Success: %@", jsonObject);

         NSDictionary *jsonDictionary = (NSDictionary *)jsonObject;

         if (completion)
             completion(jsonDictionary, YES);

     } failure:^(AFHTTPRequestOperation *operation, NSError *error)
     {
         NSLog(@"%@ AFError: %@", self.class, [error localizedDescription]);

         completion(nil, NO);
     }];
}

然后,当我需要调用该方法时,我这样做:

NSDictionary *parameters = @{@"email":@"me@example.com", @"password":@"mypassword"};

[ZAPRootViewController jsonRequestWithBaseURL:@"http://www.myserver.com/" function:@"login.php" parameters:parameters completion:^(NSDictionary *json, BOOL success)
     {
         if (success)
             {
                 //do something
             }
     }];