加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

objective-c – AFHTTPClient – 解析响应对象

发布时间:2020-12-16 07:31:24 所属栏目:百科 来源:网络整理
导读:我刚开始使用AFNetworking,我正在努力学习如何正确地完成它. 我将AFHTTPClient子类化,并使用正确的基本URL创建了我自己的MyAppClient. 我正在使用HTTP POST请求和服务器响应与xml通信我的服务器. 发送请求我做: [[MyAppClient sharedClient] postPath:someP
我刚开始使用AFNetworking,我正在努力学习如何正确地完成它.
我将AFHTTPClient子类化,并使用正确的基本URL创建了我自己的MyAppClient.
我正在使用HTTP POST请求和服务器响应与xml通信我的服务器.

发送请求我做:

[[MyAppClient sharedClient] postPath:somePath parameters:nil success:^(AFHTTPRequestOperation *operation,id responSEObject) {

    // need to parse the data here...

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

几个问题:

>为什么AFHTTPClient使用操作,如果它使用不阻塞主线程的异步NSURLConnection?
>在我获取需要解析的数据之后,我现在应该创建一个新的操作来解析数据吗?
在我看来,在操作中解析数据然后返回解析后的对象会更好吗?
>在同一主题中,我有一个自定义通用XMLParser类,它获取NSData并将其解析为NSDictionary,我想将它用于所有响应,如何将其集成到AFHTTPClient AFHTTPRequestOperation中,以便响应将是已解析?

解决方法

Why does the AFHTTPClient use operation if anyway it’s using an asynchronous NSURLConnection that doesn’t block the main thread?

这实际上是一个很好的问题.

实际上,从NSOperation继承子类并不是一个可行的“HTTPRequestOperation”类. AFHTTPRequestOperation的设计很可能基于苹果工程师“Quinn”所引入的“原创”设计,他使用他的QHTTPOperation课程发明了第一个“参考设计”,并提供了许多宝贵的样本 – 仍然强烈推荐值得一看.第一个设计是NSOperation的子类,并封装了一个NSURLConnection对象.

这种设计有许多优点:

>由于它是NSOperation的子类,因此网络请求看起来像是“异步操作”.这意味着,网络请求基本上具有启动和取消的主要方法,并具有完成处理程序以指示请求的最终结果.此通用API对于异步网络操作很重要,因此它将成为更通用的异步操作.
>由于它是一个类,它封装了一个请求的所有相关状态变量.例如,请求,响应,响应数据,错误(如果有)以及一些更相关的状态变量.然后,“网络请求对象”变得非常方便使用,与委托方法不同,当在一个委托对象中的委托方法中处理多个请求时,它开始变得困难.
> NSOperation对象可以排队到NSOperationQueue中.这使得可以定义请求的顺序,特别是任何其他操作,以及同时活动操作(请求)的数量(如果您有许多).
>使用NSOperation,可以在其他操作中定义或多或少的复杂依赖关系,这允许您添加一些额外的“业务逻辑”层.偶尔,这对于解决更复杂的异步问题变得非常方便.

因此,为什么已经异步NSURLConnection被封装在NSOperation的子类中的问题是上述优点.原因是永远不要将它像同步函数一样包装到NSOperation中,以便它可以在NSOperationQueue中执行.

事实上,对此存在广泛的误解.看来,许多人认为网络请求操作的方法将在NSOperation的执行上下文中执行(例如,当添加到NSOperationQueue时).然而,情况并非如此(在各种其他实现中可能存在少量例外).方法的执行上下文(主要是NSULRConnection的委托方法)是一个专用的私有线程,它将由NSOperation子类创建.无论如何,底层NSURLConnection的低级函数也在其私有执行上下文(一个或多个线程)上执行.

只有start方法才会在操作的执行上下文中执行,后者会快速返回.也就是说,如果存在已调度操作的队列(例如调度队列或NSOperationQueue),则只有start方法在队列的执行上下文上执行.

然而,NSOperation的isFinished状态将被推迟到网络请求确实完成的程度.这个状态对于其他NSOperation对象和NSOperationQueue具有重要意义:它表示该请求已完成的队列和其他操作.

因此,NSOperation不是定义网络请求功能的执行上下文的工具,而是组织和设置与其他操作的关系的手段.

After I’m getting the data I need to parse it,should I now create a new operation to parse the data?
It seems to me that it would be better to parse the data also in the operation and then return the parsed objects no?

好吧,你可以做到.但是,我不认为这是一个好的设计决策:操作应该只处理特定的任务.网络操作是一个,解析任务_是另一个任务,也可以是一个操作.

其中一个原因是操作可以“分类”它们主要需要哪些系统资源:CPU,内存,IO等.合并不同的“任务类型”使得无法利用它们将它们与专用队列相关联以便控制利用系统资源(见下文).

当然,你可以将解析任务作为一个操作.这是否有意义,取决于:

您是否要将特定任务(或功能)作为NSOperation的决定取决于以下注意事项:

>“操作”是合理的,如果该任务可能需要很长时间才能完成(从用户的角度来看),因此您(作为开发人员)希望用户有机会取消任务:(您还记得:异步操作)有主要方法取消)
>另一个原因是将操作与特定的执行上下文相关联,后者本身与特定的共享和有限的系统资源相关联 – 如CPU,IO等.这使您可以控制例如需要执行的并行执行操作的数量.某些系统资源.说,你有一个“磁盘绑定”任务.在这种情况下,您可以创建一个NSOperationQueue,其并发操作数为1,并为其提供特定的“角色”和合适的名称,例如“DiskBoundQueue”.该队列可帮助您控制创建和操作的开始,并强制限制并行执行操作的数量,以便不会耗尽受限制的系统资源.然后,只能将“磁盘绑定”操作添加到专用的“DiskBoundQueue”.由于磁盘在同时从不同任务访问时运行次优,因此并发操作的数量设置为1.也就是说,此类专用队列有助于优化系统资源的利用率.
>如果操作之间存在依赖关系,则表示只有在操作A AND操作B成功完成时才要启动操作C. NSOperation提供了建立这种依赖关系的方法.
>另一个原因可能是控制对共享资源的并发访问:如果有多个操作访问添加到串行NSOperationQueue的某个共享资源(例如,ivar),则对该共享资源的访问被序列化,因此“线程安全“.但是,如果并发是唯一的要求,我宁愿使用更简单的方法来利用调度队列和块.

所以,为了更准确地对待你的问题:不,NSOperation可能会超大.您可能更好地使用专用的调度队列,可能是串行的,也可以解决共享资源的并发访问.

At the same subject I have a custom generic XMLParser class that gets a NSData and parse it to NSDictionary,and I would like to use it for all of the responses,how can I integrate it in the AFHTTPClient AFHTTPRequestOperation so that the response will be already parsed?

一种可行的方法是在AFHTTPRequestOperation或AFClient的完成处理程序中启动XML解析器.

如果您有另一个依赖于XML解析器结果的操作,那么一种方法是将XML解析器封装在NSOperation中,然后使另一个操作依赖于XML解析器操作. (尽管如此,还有其他更简单的解决方案可用于此类依赖项)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读