gpt4 book ai didi

ios - 具有依赖性的 AFHTTPSessionManager 和 NSOperation 队列(AFNetworking 2)

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:10:14 25 4
gpt4 key购买 nike

在以前版本的 AFNetworking 上,我可以使用 AFHTTPRequestOperation 来创建多个请求,在它们之间创建依赖关系并很容易地将它们排入队列。示例(在 AFHTTPClient 子类中):

NSURLRequest *categoriesRequest = [self requestWithMethod:@"GET" path:@"categories" parameters:nil];
AFHTTPRequestOperation *categoriesOperation = [self HTTPRequestOperationWithRequest:categoriesRequest success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSArray *jsonCategories = responseObject;
for (NSDictionary *jsonCategory in jsonCategories) {
SPOCategory *category = [[SPOCategory alloc] initWithDictionary:jsonCategory];
[self.categories addObject:category];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// …
}];

NSURLRequest *incidencesRequest = [self requestWithMethod:@"GET" path:@"incidences" parameters:nil];
AFHTTPRequestOperation *incidencesOperation = [self HTTPRequestOperationWithRequest:incidencesRequest success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSArray *jsonIncidences = responseObject;
for (NSDictionary *jsonIncidence in jsonIncidences) {
SPOIncidence *incidence = [[SPOIncidence alloc] initWithDictionary:jsonIncidence];
[self.incidences addObject:incidence];
}

completionBlock(self.incidences, self.categories, nil);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// …
}];

[incidencesOperation addDependency:categoriesOperation];

[self enqueueBatchOfHTTPRequestOperations:@[categoriesOperation, incidencesOperation] progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
// Processing…
} completionBlock:^(NSArray *operations) {
// Completed
}];

我知道我可以继续使用 AFHTTPRequestOperation 但是,我想知道在 AFHTTPSessionManager 的子类中是否有类似的方法来实现同样的事情>,使用 NSURLSession 作为支持库而不是 NSURLConnection

谢谢!

最佳答案

AFHTTPSessionManager 的连接工厂方法创建将由 NSURLSessionDataTask 对象表示的连接。

AFHTTPRequestOperation 不同,它们不是 NSOperation 子类,因此无法声明依赖关系。

可以想象像这样包装一个工厂方法

- (NSURLSessionDataTask *)GET:(NSString *)URLString
parameters:(NSDictionary *)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;

进入返回 NSOperation 对象的辅助方法/函数。不过,这可能(将)变得很麻烦,而且看起来很奇怪。

如果你有足够的勇气考虑另一个第三方库,你可以按照下面的解释解决你的问题:

想法是用“Promise”表示异步操作的最终结果。将 Promise 视为结果的占位符,最终将由操作设置。所以,基本上你将一个工厂方法包装到一个工厂方法中,然后有效地产生一个具有这个签名的方法:

-(Promise*) fetchCategories;

-(Promise*) fetchCategoriesWithParameters:(NSDictionary*)parameters;

请注意,上述方法是异步 - 但它们没有完成处理程序。 Promise 将改为提供此功能。

最初,当 fetchCategories 返回时,promise 对象并不“包含”结果。

您通过分别“注册”完成处理程序 block 错误处理程序 block 分别获得(在稍后的某个时间)最终结果和错误> 像这样的 then 属性(伪代码):

  [self.fetchCategoriesWithParameters].then( 
<success handler block>,
<failure handler block> );

更完整的代码片段:

Promise* categoriesPromise = [self fetchCategories];

categoriesPromise.then(^id(id result){
self.categories = result;
... // (e.g, dispatch on main thread and reload table view)
return nil;
}, ^id(NSError* error){
NSLog(@"Error: %@", error);
return nil;
});

注意:成功处理程序 block 的参数result 是操作的最终结果,也就是responseObject

现在,为了“链接”多个异步操作(包括处理程序),您可以这样做:

self.categoriesPromise = [self fetchCategories];

Promise* finalResult = self.categoriesPromise.then(^id(id result){
NSArray *jsonCategories = result;
for (NSDictionary *jsonCategory in jsonCategories) {
SPOCategory *category = [[SPOCategory alloc] initWithDictionary:jsonCategory];
[self.categories addObject:category];
}
return [self fetchIncidencesWithParams:result);
}, nil)
.then(^id(id result){
NSArray *jsonIncidences = result;
for (NSDictionary *jsonIncidence in jsonIncidences) {
SPOIncidence *incidence =
[[SPOIncidence alloc] initWithDictionary:jsonIncidence];
[self.incidences addObject:incidence];
}
return @[self.incidences, self.categories];
}, nil)
.then(^id(id result){
NSArray* incidences = result[0];
NSArray* categories = result[1];
...
return nil;
}, nil /* error handler block */);

您创建并“解决”(即设置结果)一个 Promise,如下所示:

- (Promise*) fetchCategories {
Promise* promise = [[Promise alloc] init];

NSURLRequest *categoriesRequest = [self requestWithMethod:@"GET" path:@"categories" parameters:nil];
AFHTTPRequestOperation *categoriesOperation = [self HTTPRequestOperationWithRequest:categoriesRequest success:^(AFHTTPRequestOperation *operation, id responseObject) {
[promise fulfillWithResult:responseObject];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[promise rejectWithReason:error];
}];

return promise;
}

免责声明:

有一些第三方 Objective-C 库以这种或类似的方式实现 Promise。我是 RXPromise 的作者根据 Promises/A+ 实现 promise 规范。

关于ios - 具有依赖性的 AFHTTPSessionManager 和 NSOperation 队列(AFNetworking 2),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19406777/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com