美文网首页
Reading Code TWO

Reading Code TWO

作者: iLeooooo | 来源:发表于2018-03-14 09:48 被阅读3次

引入:读AFNetworking ~> '0.5.1'

一、NSAutoreleasePool

虽然ARC引入之后NSAutoReleasePool的使用有了很大变化,但是了解NSAutoReleasePool的机制还是十分必要的,下面主要说一下:

NSAutoReleasePool * pool = [NSAutoReleasePool alloc] init];
//do something
[[NSRunLoop currentRunLoop] run];
[pool drain];

之后,
[pool drain][pool release] 的区别:

  1. release,在引用计数环境下,由于NSAutoReleasePool是一个不可以被retain的类型,所以release会直接dealloc pool对象。当pool被dealloc的时候,pool向所有在pool中的对象发出一个release的消息,如果一个对象在这个pool中autorelease了多次,pool对这个对象的每一次autorelease都会release。在GC环境下release是一个no-op操作(代表没有操作,是一个占据进行很少的空间但是指出没有操作的计算机指令)。

  2. drain,在引用计数环境下,它的行为和release是一样的。在GC的环境下,这个方法调用objc_collect_if_needed出发GC。

因此,重点是:在GC环境下,release是一个no-op,所以除非你不希望在GC环境下出发GC,你都应该使用drain而不是使用release来释放pool。

引入:

- (void)setCancelled:(BOOL)isCancelled {
    [self willChangeValueForKey:@"isCancelled"];
    _cancelled = YES;
    [self didChangeValueForKey:@"isCancelled"];

    self.state = AFHTTPOperationFinishedState;
}
二、键-值编码(KVC)、KVO、NSNotificationCenter
键-值编码 KVC

setValue:forKey:通过名称(字符串)设置任何属性的值,字符串可在运行时修改

[aObject setValue:theValue forKey:theKey];

valueForKey:从对象中获取属性的值

NSString *aString = [aObject valueForKey:theKey];

其实与getter,setter一样,但更加灵活。

键-值观察 Key-Value Observing, KVO

控制器获知何时更新视图

  • 反复检查模型观察是否有任何更改
    1. 创建计时器,定期从模型中获取最新值,并提供给视图
    2. 浪费资源:时间,CPU,电池
  • 等待模型向控制器通知变化
  • 允许对象注册为 当另一个对象 更改它的一个属性的值时收到通知
  • 注册更改通知
  1. 当属性修改时,需要被通知的对象(观察者)
  2. 被观察者的属性名称
  3. 当一个变化发生时,观察者应该被告知的信息
  4. [optional]包含一个指针或引用,当属性值发生变化时,指针或对象引用应该被传递到运行的方法中
  • 注册(添加)通知
[aProduct addObserver:self
           forKeyPath:@"productName"
              options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
              context:nil];
  • 当一个对象被注册为另一个对象的一个观察者时,该对象(如:观察者)将接收observeValueForKeyPath:ofObject:change:context:消息

  • 属性发生变化的对象

  • 发生变化的属性对象

  • 一个包含变化信息的NSDictionary

  • 当此消息被调用时,context变量将传递进去

 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if([keyPath isEqualToString:@"productName"])
    {
        NSString *newName = [change objectForKey:NSKeyValueChangeNew];
    
        //通知响相应视图根据newName变量的值进行更新
    }
}
  • NSDictionary包含不同的信息和其他键
  • NSKeyValueObservingOptionNew 属性要被设置的值
  • NSKeyValueObservingOptionOld 属性之前的值
  • 将变化通知给观察者

使用了Objective-C的属性@property,当setter被调用时,Cocoa自动通知任何已注册的观察者

不使用属性,或重写了setter,需要手动通知系统

对self对象调用willChangeValueForKey与didChangeValueForKey,跟踪新值,旧值
重写setter,同时允许KVO工作

- (void) setProductName:(NSString *)newProductName
{
    [self willchangeValueForKey:@"productName"];
    productName = newProductName;
    [self didChangeValueForKey:@"productName"];
}
使用NSNotification进行通知

某些相关联的事情发生,使用广播通知
按下Home键

  1. NSNotification对注册对象发送广播通知,由NSNotificationCenter管理,是单例对象
    相应Home键按下
  2. 注册通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationEnteredBackground:) UIApplicationDidEnterBackgroundNotification object:nil];
  1. UIApplicationDidEnterBackgroundNotification传递出去,注册的对象将运行applicationenteredBackground:方法,此方法定义在该对象所属类中
- (void)applicationEnteredBackground:(NSNotification *)notification
{
    //进入后台,进行处理
}
  1. 不希望接收到消息
[[NSNotificationCenter defaultCenter] removeObserver:self]

引入:

在阅读AFN的源码的时候,发现只有(HTTP、Image)RequestOperation和AFRestClient。RequestOperation很好理解就是一项请求操作,里面包括了NSURLConnection的代理方法,在这里进行网络请求,得到服务器返回的数据,但是在这里并没有执行这个操作,只是把这个请求操作封装好了。(这个时候我就想应该会在某个地方调用[operation start]这个方法来获取数据,但是我搜索整个库,发现并没有地方调用这个操作,这就很纳闷了)AFN是怎么开始开始请求的呢,后面发现在AFRestClient里面用到了这个operation,AFRestClient先是对请求头,请求方法和请求参数进行了一次封装,然后就是执行相应的RequestOperation,但是这里也没有调用[operation start],只是调用了[self.operationQueue addOperation:operation]这时候去查资料,才有了下面的内容

AFHTTPRequestOperation *operation = [AFJSONRequestOperation operationWithRequest:request success:success failure:failure];
[self.operationQueue addOperation:operation];
三、Operation
  • 系统自动将NSOperationqueue中的NSOperation对象取出,将其封装的操作放到一条新的线程中执行。
    提示:队列的取出是有顺序的,与打印结果并不矛盾。这就好比,选手A,B,C虽然起跑的顺序是先A,后B,然后C,但是到达终点的顺序却不一定是A,B在前,C在后。
  • 只要NSBlockOperation封装的操作数 > 1,就会异步执行操作
  • NSOperationQueue的作⽤:NSOperation可以调⽤start⽅法来执⾏任务,但默认是同步执行的
  • 如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作
  • 添加操作到NSOperationQueue中,自动执行操作,自动开启线程
  • 操作对象默认在主线程中执行,只有添加到队列中才会开启新的线程。即默认情况下,如果操作没有放到队列中queue中,都是同步执行。只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作。
  • 当我们把operation添加到队列中去后,就相当于把operation交给了系统,然后由系统决定它的执行顺序。
    从网上摘抄了一篇非常详细的Operation介绍
四、AFNetworking的内容
  • AFHTTPRequestOperation(NSOperation)

封装一整套请求操作,有NSURLConnection的代理方法,得到服务器返回的数据,还有对抽象类NSOperation的具体实现,是下面图片链接请求和JSON数据请求的基类

  • AFImageCache(NSCache)

对图片进行缓存和获取缓存图片,使用的是图片链接+图片的尺寸当做key缓存的

  • AFImageRequestOperation(AFHTTPRequestOperation)

单独对网络图片请求进行封装,对图片进行简单的处理,同时在请求到图片后,对图片进行缓存

  • AFJSONRequestOperation(AFHTTPRequestOperation)

处理返回结果,把结果JSON格式化,首先是判断没有错误,然后判断是否包含正确的状态码,如果不包含,自定义error,再判断是否包含正确MIMEType,如果不包含,自定义error,再判断如果错误,返回failure块,包含请求,响应,错误,如果返回结果长度为0,直接返回success,最后异步处理正常情况,请求成功,有数据,如果系统版本大于4.3,使用系统自带的NSJSONSerialization,对返回数据JSON化,如果小于4.3,使用第三方框架JSONKit,对返回数据JSON化,处理成功返回success(request, response, JSON),处理失败返回failure(request, response, JSONError)

  • AFNetworkActivityIndicatorManager(NSObject)

对状态栏网络信号小菊花的简单封装,开始和结束动画

  • AFRestClient(NSObject)

真正开始请求网络的地方,包含get、post、pull、delete请求方法,也可以取消网络请求,设置请求头

  • NSData + AFNetworking

NSData的扩展,包括base64编码,压缩和解压,使用的是zlib压缩函式库

  • NSMutableURLRequest + AFNetworking

NSMutableURLRequest的扩展,提供对请求体的处理方法

  • NSString + AFNetworking

NSString的扩展,提供对请求链接url使用当初ASI里面的方法编码CFURLCreateStringByAddingPercentEscapes

  • UIImage + AFNetworking

UIImage扩展,对UIImage进行裁剪,带圆角的裁剪

  • UIImageView + AFNetworking

UIImageView的扩展,提供给我们之间使用的,设置网络图片链接给UIImageView来展示图片,如果有缓存改图片,之间去缓存图片,取消网络请求

简单整理,如果错误,欢迎指正,谢谢~
持续更新

相关文章

网友评论

      本文标题:Reading Code TWO

      本文链接:https://www.haomeiwen.com/subject/tjcpfftx.html