SDWebImage源码阅读(二)NSData+ImageContentType

  NSData+ImageContentType 是NSData 的分类(Category)。

  创建分类的步骤:

  在Xcode 工程页面,按command + N ,在iOS -> Source 选择Objective-C File ,点击Next ,File Type 选择 Category ,file 框里输入分类名字,Calss 为要添加分类的类,可以是系统的类也可以是自定义的类,当然这里出现的主要是系统的类。

  分类的描述:

  无论一个类设计的如何完美,都不可避免的会遇到没有预测到的需求,那怎么扩展现有的类呢?当然,继承是个不错的选择。但是Objective-C 提供了一种特别的方式来扩展类,叫Catagory,可以动态的为已经存在的类添加新的行为。这样可以保证类在原来的基础上,较小的改动就可以增加需要的功能。使用Category  对类进行扩展时,不需要访问其源代码,也不需要创建子类,这样我们就可以扩展系统提供的类。Category使用简单的方式,实现了类的相关方法的模块化,把不同的类方法分配到不同的分类文件中。
  使用Objective-C 中的分类Category,利用OC 的动态运行时分配机制,是一种编译时的手段,允许我们给一个已经存在的类添加方法来扩充它(但是通过category不能添加新的实例变量),并且我们不需要访问原有类中的代码就可以做到。

  分类的功能作用: 

  • 即使在你不知道一个类的源码的情况下,可以在不修改原来类的基础上向这个类添加扩展方法,主要用来给系统自带的类扩展方法
  • 将类的实现分散到多个不同文件或多个不同框架中。
  • 创建对私有方法的前向引用。(实现对基类中私有方法(就是没在.h 文件中声明)的访问,在基类中有一个私有方法 a(),直接访问是不行的,就需要在分类中.h 文件中声明一下这个方法,然后就可以调用了)
  • 向对象添加非正式协议。
  • 使用分类为类添加方法,通过在.h 文件中声明一个额外的方法并且在.m 文件中实现方法即可。分类的名字(也就是括号括起来的自定义字符串)表示的是:对于声明于其他地方的某个类,在此处添加的是他的额外的方法,而不是表示这是一个新的类。
  • Category 只能添加“方法”,不能增加成员变量,Category 中可以访问原来类中的成员变量,但是只能访问@protected 和 @public 形式的变量,如果想要访问本类中的私有变量,分类和子类一样,只能通过方法来访问。如果分类中声明了一个属性,那么分类只会生成这个属性的set、get方法声明,也就是不会生成set 、get 方法的实现。(如果想添加实例变量,那就通过继承创建子类来实现)
  • Category可以重新定义新方法,可以重载原始类的方法,不推荐这么做,这样会覆盖掉原始类的方法。如果确实要重载,那就通过继承创建子类来实现。

  类属性修饰符延伸: 

  Objective-C 中,类的实例化变量的范围有@private、@protected、@public。他们代表的意思和C++中相同,只是前面添加了一个@符号。下面介绍一下他们代表的范围:

  • @pribate :作用范围只能在自身类
  • @protected :作为范围在自身类和继承自己的子类,什么都不写的时候默认就是此属性
  • @public :作用范围最大,在任何地方

  分类的执行优先级:

  • 在本类和分类有相同的方法时,优先调用分类的方法再调用本类的方法。
  • 如果有两个分类,他们都实现了相同的方法,如何判断谁先执行?分类执行顺序可以通过TARGETS -> Build Phases -> Compile Sources 进行调节,注意执行顺序是从上到下的。(只有两个分类含有相同的方法名)

  类扩展(class Extensions)

  类扩展(Extension) 是Category 的一个特例,有时候也被称为匿名分类。他的作用是为一个类添加一些私有的成员变量和方法。和分类不同,类扩展即可以声明成员变量又可以声明方法。

  类扩展(Extension) 只有接口文件(.h),没有实现文件(.m) 定义的方法通通在类里边实现。类扩展听上去很复杂,但其实我们早就认识他了,当我们创建一个继承自UIViewControll的子类时,在它的.m 文件里面会自动生成类扩展:

@interface ExtensionsViewController ()

@end

  我们可以在里面添加私有属性和私有方法,私有方法需要在下面的@implementation 里面实现。

  当然类扩展可以定义在.m 文件中,这种扩展方式中定义的变量都是私有的,也可以定义在.h 文件中,这样定义的代码就是公有的,类扩展在.m 文件中声明私有方法是非常好的方式。类扩展中添加的方法,一定要实现,不然会有编译警告。

1 #import "ExtensionsViewController.h"
2
3 @interface ExtensionsViewController ()
4
5 @end
6
7 @implementation ExtensionsViewController
8
9 ...

  类扩展的作用:

  • 能为某个类附加额外的属性,成员变量,方法声明
  • 一般的类扩展写到.m文件中
  • 一般的私有属性写到类扩展

  使用格式:

1 #import "ViewController.h"
2
3 @interface ViewController ()
4
5 // 属性
6 // 方法
7
8 @end

  分类和类扩展的相似之处是:都可以为类添加一个额外的方法。

 不同之处在于:

  • 分类的括号里面必须有名字:
 1 // .h
 2 @interface 类名(分类名字)
 3
 4 /*方法声明*/
 5
 6 @end
 7
 8 // .m
 9 @implementation类名(分类名字)
10
11 /*方法实现*/
12
13 @end
  • 分类只能扩充方法,不能扩展属性和成员变量(如果包含成员变量会直接报错)。
  • 再说一下我们为什么不能包含类的.m 文件,因为这样会重复包含另一类的实现文件。

参考链接:http://blog.csdn.net/jiajiayouba/article/details/21104987

http://www.jianshu.com/p/18d48e7f2aad

http://www.cnblogs.com/sgdkg/p/3142647.html

http://blog.csdn.net/kindazrael/article/details/8062784

http://www.cocoachina.com/ios/20161018/17784.html

http://www.jb51.net/article/80246.htm

http://www.2cto.com/kf/201504/387630.html

http://blog.csdn.net/qq_30513483/article/details/52068424

http://www.tuicool.com/articles/AV7fiy

时间: 2025-01-01 09:59:07

SDWebImage源码阅读(二)NSData+ImageContentType的相关文章

【原】SDWebImage源码阅读(二)

[原]SDWebImage源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 解决上一篇遗留的坑 上一篇中对sd_setImageWithURL函数简单分析了一下,还留了一些坑.不过因为我们现在对这个函数有一个大概框架了,我们就按顺序一个个来解决. 首先是这一句代码: objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 就是给UIImageVi

【原】SDWebImage源码阅读(一)

[原]SDWebImage源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 一直没有系统地读过整套源码,就感觉像一直看零碎的知识点,没有系统读过一本专业经典书籍一样,会有点发虚,感觉知识体系不健全!废话少说,这次我决定好好阅读下SDWebImage的源码,我的阅读方式,是带着问题去阅读源码,然后强迫自己写博客. 2. SDWebImage是做什么的? 既然是要带着问题读,那么第一个问题就来了,SDWebImage是做什么的?SDWebImage是一个开源

SDWebImage源码阅读-第三篇

这一篇讲讲不常用的一些方法. 1 sd_setImageWithPreviousCachedImageWithURL: placeholderImage: options: progress: completed: 取得上次缓存的图片,然后作为占位图的参数再次进行一次图片设置. - (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options

【原】SDWebImage源码阅读(三)

[原]SDWebImage源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1.SDWebImageDownloader中的downloadImageWithURL 我们来到SDWebImageDownloader.m文件中,找到downloadImageWithURL函数.发现代码不是很长,那就一行行读.毕竟这个函数大概做什么我们是知道的.这个函数大概就是创建了一个SDWebImageSownloader的异步下载器,根据给定的URL下载image. 先映入眼帘的

【原】SDWebImage源码阅读(五)

[原]SDWebImage源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 前面的代码并没有特意去讲SDWebImage的缓存机制,主要是想单独开一章节专门讲解缓存.之前我们也遇到一些缓存的属性和方法,比如storeImage.queryDiskCacheForKey.memCache等等. SDWebImage的缓存分为两个部分,一个内存缓存,使用NSCache实现,另一个就是硬盘缓存(disk),使用NSFileManager实现. 不过这么多函数,

SDWebImage源码阅读(四)SDWebImageDecoder

一般我们都是使用: 1 + (nullable UIImage *)imageNamed:(NSString *)name; // load from main bundle 和: 1 + (nullable UIImage *)imageWithContentsOfFile:(NSString *)path; 两种方式加载图片,它们两个的区别在SDWebImage源码阅读前的准备(三)UIImage.h 里面的 "(六):加载和创建UIImage 的类方法和实例方法:"部分有详细的介

OSCache源码阅读(二)

前文LRU Cache 暨LinkedHashMap源码阅读提到了如何使用LinkedHashMap来实现一个LRU数据结构,今天在看OSCache代码算法部分的时候,就用到了该知识,what was done contributes what is done now. algorithm包是包含下列缓存过期策略的类: 下面重点介绍LRU和FIFO. LRU private Collection list = new LinkedHashSet(); 使用一个LinkedHashSet对象来实现

SDWebImage源码阅读(三)UIImage+GIF

UIImage+GIF 是UIImage 类的一个GIF 分类,在之前的版本里面这个分类是用了处理GIF 动态图片的但是会有内存暴增的bug.在当前 '4.0.0-beta2' 的版本里GIF 动态图片处理放在了UIImage+MultiFormat  这个分类里面,而当前这个GIF 的分类的功能只是将动态图片作为静态图片来处理,如果是静态图片的NSData 数据则转化为静态UIImage 直接返回,如果是动态图片的NSData 数据,则把图像的第1帧图像转换化为静态UIImage 返回. 首先

spring源码阅读(二) Bean加载之自定义标签加载

紧接着上一篇关于spring默认标签加载,这一篇来看下自定义标签的加载 继续从 DefaultBeanDefinitionDocumentReader来看 protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(root)) { NodeList nl = root.getChildNodes(); for(