SDWebImage源碼解讀(一)NSData+ImageContentType

前言
從事iOS開發(fā)有一段時間了,為了成長,決定開始著手寫博客。這一階段,博客主要內(nèi)容是解讀諸如:SDWebImage、AFNetWorking等優(yōu)秀的開源框架。

這段時間一直在拜讀博客園大神馬在路上的博客,他就有關(guān)于SDWebImage的解讀,很詳細(xì),把很多值得學(xué)習(xí)的知識點(diǎn)凸顯了出來,我受益匪淺。但是作為新手,這些框架源碼中還是有很多我不太懂的細(xì)節(jié)知識點(diǎn),所以,我的目標(biāo)就是去解讀細(xì)碎的知識點(diǎn),讓自己能建立一個更加牢固的基礎(chǔ)知識體系。歡迎批評指正!

解讀方法:先從頭文件開始,分析類功能,每個方法功能,然后解讀.m文件方法的具體實(shí)現(xiàn)。

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

  • (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data;
    復(fù)制代碼
    這個類是NSData的分類,分類作用是對類的功能擴(kuò)展。所以這個類是用來處理data的。

這個頭文件很簡單,方法返回SDImageFormat是一個文件格式。

文件頭:

定義:文件頭是位于文件開頭的一段承擔(dān)一定任務(wù)的數(shù)據(jù)。一般都在開頭的部分。

解釋:文件頭則是直接位于文件中的一段數(shù)據(jù),是文件的一部分。計算機(jī)中的文件有很多類型,而相同類型的文件一般還會多多少少有一些不同的地方,文件的類型有EXE,COM,BMP,GIF,WMV,APE,RMVB,FLV,SWF,TXT,CPP,ASM等等。當(dāng)然有的文件沒有文件頭,比如TXT,系統(tǒng)根據(jù)擴(kuò)展名來識別文件,然后用不同的程序來打開這個文件。但是相同類型的文件也是有不同的地方的,比如相同一張圖片,但是文件大小不同,而系統(tǒng)就可以根據(jù)文件頭來識別文件大小。簡單來說,文件頭是用來區(qū)分文件是什么類型的。

文件頭的類型有很多,下面列舉一些文件頭:

1.JPG,文件頭:FFD8FFE1

2.PNG,文件頭:89504E47

3.GIF,文件頭:47494638

4.TIFF,文件頭:49492A00

5.WebP,文件頭:524946462A73010057454250

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

復(fù)制代碼
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 }
復(fù)制代碼
這里我們進(jìn)行逐行解讀:

unit8_t c;點(diǎn)擊跳轉(zhuǎn)我們可以看到

typedef unsigned char uint8_t;
typedef的意思就是,用后者代替前者。用unit8_t來表示無符號char。而char在C語言中表示字符型,長度為一個字節(jié)。

[data getBytes:&c length:1];點(diǎn)擊跳轉(zhuǎn)我們可以看到
1 - (void)getBytes:(void *)buffer length:(NSUInteger)length;
這個是NSData的方法,這個方法的作用是取出length個字節(jié),存入buffer中。所以這行代碼的作用是,取出文件data的第一個字節(jié),然后存入c中。

接下來,我們可以看到是switch分支語句,判斷取出的這個字節(jié)的內(nèi)容,返回對應(yīng)的文件格式。

當(dāng)c==0x52時,判斷了data的長度,如果長度小于12,則此文件一定不是WebP。

NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
如果大于12,則取出0-12個字節(jié)的數(shù)據(jù),然后轉(zhuǎn)為ASCII編碼,判斷字符串,若字符串是以RIFF開頭,或者以WEBP結(jié)尾,則文件為WebP格式。

總結(jié):
這個類功能比較簡單,就是根據(jù)文件二進(jìn)制數(shù)據(jù),返回文件格式。是利用分類對NSData進(jìn)行功能擴(kuò)展。

轉(zhuǎn)載:http://www.cnblogs.com/cbios/p/7350995.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容