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进行功能扩展。

欢迎批评指正!

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值