AFNetworking2.0源代码解析
写在前面给大家推荐一个不错的站点 点击打开链接
AFNetworking的代码还在不断更新中,我看的是AFNetworking2.3.1。
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wgnu"
- //code
- #pragma clang diagnostic pop
:符号,所以常常见忽略-Wgnu警告的写法。详见这里。
- static dispatch_queue_t url_request_operation_completion_queue() {
- static dispatch_queue_t af_url_request_operation_completion_queue;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- af_url_request_operation_completion_queue = dispatch_queue_create("com.alamofire.networking.operation.queue", DISPATCH_QUEUE_CONCURRENT );
- });
- return af_url_request_operation_completion_queue;
- }
- __weak __typeof(self)weakSelf = self;
- self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{
- __strong __typeof(weakSelf)strongSelf = weakSelf;
- }];
这表明仅仅有当前线程的Runloop 处于 NSDefaultRunLoopMode 时,这个任务才会被运行。
但当用户滚动 tableview 或 scrollview 时。主线程的 Runloop
是处于 NSEventTrackingRunLoopMode 模式下的,不会运行 NSDefaultRunLoopMode 的任务。所以会出现一个问题,请求发出后。假设用户一直在操作UI上下滑动屏幕,那在滑动结束前是不会运行回调函数的,仅仅有在滑动结束。RunloopMode 切回 NSDefaultRunLoopMode,才会运行回调函数。苹果一直把动画效果性能放在第一位,预计这也是苹果提升UI动画性能的手段之中的一个。
- NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
- [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
- [connection start];
AFHttpRequestOperationManager 的接口发送请求,这些请求会统一在一个 NSOperationQueue 里去发,所以多了上面 NSOperationQueue 的一个线程。
会自己主动调用 completeBlock,再回调到上层。
持有的 completionBlock 对象,打破循环引用。
Deallocation Problem”简单来说就是不要让UIKit的东西在子线程释放。
- dispatch_group_async(group, queue, ^{
- block();
- });
- dispatch_async(queue, ^{
- dispatch_group_enter(group);
- block()
- dispatch_group_leave(group);
- });
- dispatch_group_async(group, queue, ^{
- [self performBlock:^(){
- block();
- }];
- //未运行到block() group任务就已经完毕了
- });
- dispatch_group_enter(group);
- [self performBlock:^(){
- block();
- dispatch_group_leave(group);
- }];
这样做更安全,由于序列化后的数据有可能被篡改。若不指定 Class,-decode 出来的对象可能不是原来的对象,有潜在风险。另外,NSSecureCoding 是 iOS 6 以上才有的。
详见这里。
- AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
- NSData *data = [NSKeyedArchiver archivedDataWithRootObject:operation];
- AFHTTPRequestOperation *operationFromDB = [NSKeyedUnarchiver unarchiveObjectWithData:data];
- [operationFromDB start];
在 dealloc 里须要调用 [application endBackgroundTask:] ,告诉系统这个后台任务已经完毕,不然系统会一直让你的APP执行在后台。直到超时。
- AFHTTPRequestOperation.m
AFNetworking提供了接口,让參数能够是NSDictionary, NSArray, NSSet这些类型。再由内部解析成字符串后赋给NSURLRequest。
- @{
- @"name" : @"bang",
- @"phone": @{@"mobile": @"xx", @"home": @"xx"},
- @"families": @[@"father", @"mother"],
- @"nums": [NSSet setWithObjects:@"1", @"2", nil]
- }
- ->
- @[
- field: @"name", value: @"bang",
- field: @"phone[mobile]", value: @"xx",
- field: @"phone[home]", value: @"xx",
- field: @"families[]", value: @"father",
- field: @"families[]", value: @"mother",
- field: @"nums", value: @"1",
- field: @"nums", value: @"2",
- ]
- ->
- name=bang&phone[mobile]=xx&phone[home]=xx&families[]=father&families[]=mother&nums=1&num=2
Auth 认证接口,帮你把usernamepassword做 base64 编码后放入 HTTP 请求头。
详见源代码凝视。
- AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
- NSDictionary *parameters = @{@"foo": @"bar"};
- NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];
- [manager POST:@"http://example.com/resources.json" parameters:parameters constructingBodyWithBlock:^(id formData) {
- [formData appendPartWithFileURL:filePath name:@"image" error:nil];
- } success:^(AFHTTPRequestOperation *operation, id responseObject) {
- NSLog(@"Success: %@", responseObject);
- } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
- NSLog(@"Error: %@", error);
- }];
里。
最后把 AFMultipartBodyStream 赋给原来 NSMutableURLRequest的bodyStream。NSURLConnection 发送请求时会读取这个 bodyStream,在读取数据时会调用这个 bodyStream 的 -read:maxLength: 方法。AFMultipartBodyStream 重写了这种方法,不断读取之前 append进来的 AFHTTPBodyPart 数据直到读完。
AFHTTPBodyPart 的-read:maxLength:方法。
发出请求会导致 crash,提示 [xx _scheduleInCFRunLoop:forMode:]: unrecognized selector。
bridging 机制会调用 object-c 对象 NSInputStream 的对应函数。这里就调用到了_scheduleInCFRunLoop:forMode:,若不实现这种方法就会crash。
详见这篇文章。
- AFURLRequestSerialization.m
AFNetworking2.0源代码解析的更多相关文章
- AFNetworking2.0源码解析<一>
本篇先看看AFURLConnectionOperation,AFURLConnectionOperation继承自NSOperation,是一个封装好的任务单元,在这里构建了NSURLConnecti ...
- Arrays.sort源代码解析
Java Arrays.sort源代码解析 Java Arrays中提供了对所有类型的排序.其中主要分为Primitive(8种基本类型)和Object两大类. 基本类型:采用调优的快速排序: 对象类 ...
- qemu-kvm-1.1.0源代码中关于迁移的代码分析
这篇文档基于qemu-kvm-1.1.0源代码进行分析. 首先,源代码中的hmp-commands.hx文件里有下面内容: { .name = "migrate",/* 在moni ...
- volley源代码解析(七)--终于目的之Response<T>
在上篇文章中,我们终于通过网络,获取到了HttpResponse对象 HttpResponse是android包里面的一个类.然后为了更高的扩展性,我们在BasicNetwork类里面看到.Volle ...
- Cocos2d-x源代码解析(1)——地图模块(3)
接上一章<Cocos2d-x源代码解析(1)--地图模块(2)> 通过前面两章的分析,我们能够知道cocos将tmx的信息结构化到 CCTMXMapInfo.CCTMXTilesetInf ...
- Android EventBus源代码解析 带你深入理解EventBus
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40920453,本文出自:[张鸿洋的博客] 上一篇带大家初步了解了EventBus ...
- 源代码解析Android中View的layout布局过程
Android中的Veiw从内存中到呈如今UI界面上须要依次经历三个阶段:量算 -> 布局 -> 画图,关于View的量算.布局.画图的整体机制可參见博文 < Android中Vie ...
- Android xUtils3源代码解析之网络模块
本文已授权微信公众号<非著名程序猿>原创首发,转载请务必注明出处. xUtils3源代码解析系列 一. Android xUtils3源代码解析之网络模块 二. Android xUtil ...
- Android View体系(八)从源代码解析View的layout和draw流程
相关文章 Android View体系(一)视图坐标系 Android View体系(二)实现View滑动的六种方法 Android View体系(三)属性动画 Android View体系(四)从源 ...
随机推荐
- 数组中找出最小的K个数
题目 给出一个数组,找出K个最小的值 例如给出数组{5,2,4,3,1},给定K值3,则输出结果为{2,3,1} 程序 先给出第一个版本的程序 public static void printKNum ...
- Linux6.9用RPM方式安装MySQL5.7.21
1.下载安装包 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.21-1.el6.x86_64.rpm-bundle.tar ...
- JS 判断PC、android、ios、微信浏览器
1.通过js userAgent来判断 <h1>判断访问此链接的操作系统</h1> <script> var Agents = new Array("An ...
- 使用ScrapySharp快速从网页中采集数据
ScrapySharp是一个帮助我们快速实现网页数据采集的库,它主要提供了如下两个功能 从Url获取Html数据 提供CSS选择器的方式解析Html节点 安装: ScrapySharp可以直接从Nug ...
- 利用DC/DC开关调节器延长DSP系统的电池寿命 - 动态电压调节
http://www.analog.com/zh/content/dc-to-dc_switching_regulator_insights/fca.html 作者:Sridhar Gurram,Ol ...
- jdk8 流操作
二.流 2.1 流介绍 流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现).就现在来说,你可以把它们看成遍历数据集的高级迭代器.此外,流还可以 ...
- 使用 JMeter 完成常用的压力测试
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- VS收集插件
有空再做细细解说,大部分童鞋应该都在用1.Achievements这个就是传说中的VS成就插件了,一边编程一边解锁成就 2.Spell Checker拼写检查插件,这个插件能够实时帮你检查注释或字符串 ...
- 运行Hadoop的示例程序WordCount-Running Hadoop Example
In the last post we've installed Hadoop 2.2.0 on Ubuntu. Now we'll see how to launch an example ma ...
- Symfony安装及使用
安装Symfony,使用 brew install homebrew/php/symfony-installer 开始一直下载不了包,我手动浏览器下载了几个,发现好像都是Permission问题,运行 ...