AFNetworking 2.0 AFHTTPSessionManager在委托中的表现

时间:2014-08-02 10:51:37

标签: ios swift afnetworking

我目前使用委托,称其为APIDelegate来处理来自我的View控制器的API相关请求。代表的摘录看起来像这样(Swift):

init(delegate: APIDelegateProtocol?) {
    self.delegate = delegate
}

func get(url: String, params: NSDictionary?) {
    ...blah blah...
    let manager = AFHTTPSessionManager(baseURL: baseURL, sessionConfiguration: sessionConfig)        
    manager.GET(
        url,
        parameters: params,
        success: { (task: NSURLSessionDataTask!, responseObject: AnyObject!) in
            let httpResponse: NSHTTPURLResponse = task.response as NSHTTPURLResponse
            if httpResponse.statusCode == 200 {
                self.delegate?.didReceiveAPIResults(responseObject as NSDictionary)
            } else {
                NSLog("GET Error -> Code: \(httpResponse.statusCode), Msg: \(responseObject)")
            }
        },
        failure: { (task: NSURLSessionDataTask!, error: NSError!) in
            dispatch_async(dispatch_get_main_queue(), {
                UIAlertView(title: "Networking Error", message: "GET Error -> \(url) -> \(error.localizedDescription)", delegate: nil, cancelButtonTitle: "OK").show()
                }
            )
        }
    )
}

然而,根据NSScreenCast episode on AFNetworking 2.0和其他一些网络教程,他们似乎建议创建从AFHTTPSessionManager创建子类的Singleton,类似这样(在Obj-C中复制和粘贴):

+ (ITunesClient *)sharedClient {
    static ITunesClient *_sharedClient = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSURL *baseURL = [NSURL URLWithString:@"https://itunes.apple.com/"];

        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        [config setHTTPAdditionalHeaders:@{ @"User-Agent" : @"TuneStore iOS 1.0"}];

        NSURLCache *cache = [[NSURLCache alloc] initWithMemoryCapacity:10 * 1024 * 1024
                                                          diskCapacity:50 * 1024 * 1024
                                                              diskPath:nil];

        [config setURLCache:cache];

        _sharedClient = [[ITunesClient alloc] initWithBaseURL:baseURL
                                         sessionConfiguration:config];
        _sharedClient.responseSerializer = [AFJSONResponseSerializer serializer];
    });

    return _sharedClient;
}

我的问题是: 使用AFHTTPSessionManager的Singleton子类而不是直接在AFHTTPSessionManager内调用APIDelegate有什么好处?内存管理更好吗?相对于View Controller,AFHTTPSessionManager是否已经非阻塞(调用是异步的)?

1 个答案:

答案 0 :(得分:4)

  

Isn&#t; t AFHTTPSessionManager已经相对于View Controller无阻塞(该呼叫是异步的)?

是的,两种方法都是非阻塞的。

  

使用AFHTTPSessionManager的Singleton子类而不是直接在AFHTTPSessionManager内调用APIDelegate有什么好处?内存管理更好吗?

没有明显的记忆差异。 (唯一相关的区别是您可以解除分配APIDelegate实例,但是单身人士会在应用的生命周期内闲逛。)

子类相对于您正在采用的方法的一个优点是,您可能拥有一个具有多个API调用的视图控制器。但是,在这种情况下,两个响应都会导致调用didReceiveAPIResults,然后需要尝试找出刚响应的API调用。这可能容易出错,因为网络请求并不总是按照他们所做的顺序返回。

如果采用单例方法,您的经理仍然可以隐藏视图控制器中的所有网络。

例如,如果您正在编写一个列出待售奶酪的应用,那么您的头文件可能包含:

- (void)getCheeseListWithSuccess:(void (^)(NSArray *cheeses))success
                         failure:(void (^)(NSError *error))failure;

这会隐藏来自视图控制器的数据源,如果它来自磁盘缓存,Internet或随机奶酪生成器,则不应该关心它。

为了更简洁地回答您的问题,两种解决方案都没有正式错误,但是使用完成处理程序而不是委派的解决方案可能更好。