SDWebImage源码解读(一)NSData+ImageContentType

前言
从事iOS开发有一段时间了,为了成长,决定开始着手写博客。这一阶段,博客主要内容是解读诸如:SDWebImage、AFNetWorking等优秀的开源框架。

这段时间一直在拜读博客园大神马在路上的博客,他就有关于SDWebImage的解读,很详细,把很多值得学习的知识点凸显了出来,我受益匪浅。但是作为新手,这些框架源码中还是有很多我不太懂的细节知识点,所以,我的目标就是去解读细碎的知识点,让自己能建立一个更加牢固的基础知识体系。欢迎批评指正!

解读方法:先从头文件开始,分析类功能,每个方法功能,然后解读.m文件方法的具体实现。

正文
.h:
复制代码
typedef NS_ENUM(NSInteger, SDImageFormat) {
SDImageFormatUndefined = -1,
SDImageFormatJPEG = 0,
SDImageFormatPNG,
SDImageFormatGIF,
SDImageFormatTIFF,
SDImageFormatWebP
};

  • (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data;
    复制代码
    这个类是NSData的分类,分类作用是对类的功能扩展。所以这个类是用来处理data的。

这个头文件很简单,方法返回SDImageFormat是一个文件格式。

文件头:

定义:文件头是位于文件开头的一段承担一定任务的数据。一般都在开头的部分。

解释:文件头则是直接位于文件中的一段数据,是文件的一部分。计算机中的文件有很多类型,而相同类型的文件一般还会多多少少有一些不同的地方,文件的类型有EXE,COM,BMP,GIF,WMV,APE,RMVB,FLV,SWF,TXT,CPP,ASM等等。当然有的文件没有文件头,比如TXT,系统根据扩展名来识别文件,然后用不同的程序来打开这个文件。但是相同类型的文件也是有不同的地方的,比如相同一张图片,但是文件大小不同,而系统就可以根据文件头来识别文件大小。简单来说,文件头是用来区分文件是什么类型的。

文件头的类型有很多,下面列举一些文件头:

1.JPG,文件头:FFD8FFE1

2.PNG,文件头:89504E47

3.GIF,文件头:47494638

4.TIFF,文件头:49492A00

5.WebP,文件头:524946462A73010057454250

.m文件
下面我们看.m文件

复制代码
1 + (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data {
2 if (!data) {
3 return SDImageFormatUndefined;
4 }
5
6 uint8_t c;
7 [data getBytes:&c length:1];
8 switch (c) {
9 case 0xFF:
10 return SDImageFormatJPEG;
11 case 0x89:
12 return SDImageFormatPNG;
13 case 0x47:
14 return SDImageFormatGIF;
15 case 0x49:
16 case 0x4D:
17 return SDImageFormatTIFF;
18 case 0x52:
19 // R as RIFF for WEBP
20 if (data.length < 12) {
21 return SDImageFormatUndefined;
22 }
23
24 NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
25 if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
26 return SDImageFormatWebP;
27 }
28 }
29 return SDImageFormatUndefined;
30 }
复制代码
这里我们进行逐行解读:

unit8_t c;点击跳转我们可以看到

typedef unsigned char uint8_t;
typedef的意思就是,用后者代替前者。用unit8_t来表示无符号char。而char在C语言中表示字符型,长度为一个字节。

[data getBytes:&c length:1];点击跳转我们可以看到
1 - (void)getBytes:(void *)buffer length:(NSUInteger)length;
这个是NSData的方法,这个方法的作用是取出length个字节,存入buffer中。所以这行代码的作用是,取出文件data的第一个字节,然后存入c中。

接下来,我们可以看到是switch分支语句,判断取出的这个字节的内容,返回对应的文件格式。

当c==0x52时,判断了data的长度,如果长度小于12,则此文件一定不是WebP。

NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
如果大于12,则取出0-12个字节的数据,然后转为ASCII编码,判断字符串,若字符串是以RIFF开头,或者以WEBP结尾,则文件为WebP格式。

总结:
这个类功能比较简单,就是根据文件二进制数据,返回文件格式。是利用分类对NSData进行功能扩展。

转载:http://www.cnblogs.com/cbios/p/7350995.html

你可能感兴趣的:(SDWebImage源码解读(一)NSData+ImageContentType)