gpt4 book ai didi

ios - 使用 AFNetworking 从多个资源中获取数据并返回

转载 作者:行者123 更新时间:2023-12-01 18:55:25 25 4
gpt4 key购买 nike

我正在尝试在 ObjectC 中编写一个函数,该函数返回一个具有 3 个属性的类。对于程序必须从远程服务器(现在是 AFNetworking)获取的每个属性,我想知道这个问题有什么好的解决方案?
这是我正在编写的函数的当前结构

- (MyClass *)fillInClassAndReturn {
MyClass *myClass = [MyClass new];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"Url1"
parameters:parameter1
success:^(AFHTTPRequestOperation *operation, id responseObject) {
myClass.property1 = responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
myClass.property1 = nil;
}];
[manager GET:@"Url2"
parameters:parameter2
success:^(AFHTTPRequestOperation *operation, id responseObject) {
myClass.property2 = responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
myClass.property2 = nil;
}];
[manager GET:@"Url13"
parameters:parameter3
success:^(AFHTTPRequestOperation *operation, id responseObject) {
myClass.property3 = responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
myClass.property3 = nil;
}];
return myClass;
}

此函数将返回 myClass调用此函数后,所有三个属性将立即为 nil此时,当从服务器获取相应的数据时,它会被填充。所以使用这个函数的人必须为函数的返回值定义一个KVO,并在值发生变化时得到通知。
但是这个设计有一个问题,如果返回值是 NSArray/NSMutableArray,它将不起作用而不是 MyClass那么有没有更好的设计让我可以处理这种情况?如果这个设计没有那么可怕,如何处理 NSArray*案子?

最佳答案

几点观察:

  • 因为这是一个异步运行的方法,所以您不想尝试立即返回任何内容,而是使用完成 block 模式,即 completionHandler。这将在三个请求完成后调用。
  • 由于您有三个同时运行的请求,因此您需要某种方式来了解所有三个请求何时完成。由于您使用的是 NSOperation -based 解决方案 ( AFHTTPRequestOperation ),您可以使用操作依赖项。

  • 无论如何,这会产生类似:
    - (void)fillInClassWithCompletion:(void (^)(MyClass *myClass))completionHandler {
    MyClass *myClass = [MyClass new];

    NSBlockOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
    if (completionHandler) {
    completionHandler(myClass);
    }
    }];

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    NSOperation *operation1 = [manager GET:@"Url1" parameters:parameter1 success:^(AFHTTPRequestOperation *operation, id responseObject) {
    myClass.property1 = responseObject;
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    myClass.property1 = nil;
    }];
    [completionOperation addDependency:operation1];

    NSOperation *operation2 = [manager GET:@"Url2" parameters:parameter2 success:^(AFHTTPRequestOperation *operation, id responseObject) {
    myClass.property2 = responseObject;
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    myClass.property2 = nil;
    }];
    [completionOperation addDependency:operation2];

    NSOperation *operation3 = [manager GET:@"Url13" parameters:parameter3 success:^(AFHTTPRequestOperation *operation, id responseObject) {
    myClass.property3 = responseObject;
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    myClass.property3 = nil;
    }];
    [completionOperation addDependency:operation3];

    [[NSOperationQueue mainQueue] addOperation:completionOperation];
    }

    这可能是最合乎逻辑的方法。从技术上讲,如果您更改了 completionQueueAFHTTPRequestOperationManager作为并发队列,上面引入了可能的竞争条件,因此您可以选择使用调度组机制来了解所有三个是否都已完成:
    - (void)fillInClassWithCompletion:(void (^)(MyClass *myClass))completionHandler {
    MyClass *myClass = [MyClass new];

    dispatch_group_t group = dispatch_group_create();

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    dispatch_group_enter(group);
    [manager GET:@"Url1" parameters:parameter1 success:^(AFHTTPRequestOperation *operation, id responseObject) {
    myClass.property1 = responseObject;
    dispatch_group_leave(group);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    myClass.property1 = nil;
    dispatch_group_leave(group);
    }];

    dispatch_group_enter(group);
    [manager GET:@"Url2" parameters:parameter2 success:^(AFHTTPRequestOperation *operation, id responseObject) {
    myClass.property2 = responseObject;
    dispatch_group_leave(group);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    myClass.property2 = nil;
    dispatch_group_leave(group);
    }];

    dispatch_group_enter(group);
    [manager GET:@"Url13" parameters:parameter3 success:^(AFHTTPRequestOperation *operation, id responseObject) {
    myClass.property3 = responseObject;
    dispatch_group_leave(group);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    myClass.property3 = nil;
    dispatch_group_leave(group);
    }];

    dispatch_group_notify(group, manager.completionQueue ?: dispatch_get_main_queue(), ^{
    if (completionHandler) {
    completionHandler(myClass);
    }
    });
    }

    无论哪种方式,您使用它的方式都是:
    [object fillInClassWithCompletion:^(MyClass *myClass) {
    // use myClass here
    }];

    您可能想要扩展此 completionHandler也传回一个错误对象,因为这是常见的做法,如果调用者想要根据错误的性质自定义其错误处理,这可能很有用,但我会把它留给你。

    关于ios - 使用 AFNetworking 从多个资源中获取数据并返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27613668/

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