0

我在请求失败块中发布通知:

[manager    POST:path
    parameters:nil
    success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if (operation.response.statusCode == 200) {
            //message delegate
        }
  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
      [[NSNotificationCenter defaultCenter] postNotificationName:HOST_UNREACHABLE object:operation];
}];

在接收通知的方法中,该completionBlock属性为 nil。

如何在没有子类化和覆盖的情况下访问它?

4

1 回答 1

0

首先回答如何将块发送到 NSNotification 的问题:

您尝试这样做的方式很危险,因为我们不知道 AFHTTPSessionManager 如何处理您传递的块,并且除非它在公共接口中,否则它的作用可能不会随着时间的推移而保持不变。

因此,创建一个局部变量来表示您要传递的块,例如,completionBlock...

// this is a local variable declaration of the block
void (^completionBlock)(AFHTTPRequestOperation*,id) = ^(AFHTTPRequestOperation *operation, id response) {
    if (operation.response.statusCode == 200) {
        //message delegate
    }
};

[manager POST:path
    parameters:nil
    success:completionBlock
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    [[NSNotificationCenter defaultCenter] postNotificationName:HOST_UNREACHABLE object:completionBlock];
}];

观察者可以获取块并以这种方式调用它......

- (void)didReceiveNotification:(NSNotification *)notification {
    void (^completionBlock)(AFHTTPRequestOperation*,id) = notification.object;

    // use it
    [manager POST:someOtherPath
        parameters:nil
        success:completionBlock
        // etc.
    ];
}

但我认为这种方法很奇怪。它分散了向收到通知的对象发出请求的责任,让它需要知道重试参数的路径(在这种情况下你没有,但有一天你可能会)。

考虑改为子类化管理器并添加执行重试的行为。现在您的经理子类可以负责所有请求,包括重试,而您的其他类只是处理结果的客户。就像是...

@interface MyAFHTTPRequestManager : AFHTTPSessionManager

- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                      retryURL:(NSString *)retryURLString
                    parameters:(nullable id)parameters
                       success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success
                       failure:(nullable void (^)(NSURLSessionDataTask *task, NSError *error))failure;

@end

让您的子类实现使用第一个 URLString 调用 super,如果失败,使用 retryURLString 调用 super。例如

- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                      retryURL:(NSString *)retryURLString
                    parameters:(nullable id)parameters
                       success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success
                       failure:(nullable void (^)(NSURLSessionDataTask *task, NSError *error))failure {

    [super POST:URLString parameters:parameters success:success
        failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            [super POST:retryURLString parameters:parameters success:success failure:failure];
    }];
}
于 2015-06-29T03:24:00.153 回答