###背景 SDWebImageiOS开发过程中最常使用的一个网络图片库,包括图片的下载和缓存。

主要提供的功能如下:

1.提供UIImageView, UIButton, MKAnnotationView 的分类,用来加载网络图片,并进行缓存管理; 2.异步方式来下载网络图片 3.异步方式: memory (内存)+ disk (磁盘) 来缓存网络图片,LRU自动管理缓存; 4.后台图片解码,转换及压缩; 5.同一个 URL 不会重复下载; 6.失效的 URL 不会被无限重试; 7.支持 GIF动画 及 WebP 格式; 8.使用 GCD ARC; 9.开启子线程进行耗时操作,不阻塞主线程;

###入口部分 在使用SDWebImage的时候,入口如下:

[ s e l f . i m a g e V i e w s p d l _ a s c e e t h I o m l a d g e e r W I i m t a h g U e R : L [ : U [ I N I S m U a R g L e U i R m L a W g i e t N h a S m t e r d i : n @ g " : p @ l " a u c r e l h " o ] l d e r . p n g " ] ] ;

点进去,可以看到下面这些方法:

o o o o i i i i d d d d ) ) ) ) s s s s d d d d _ _ _ _ s s s s e e e e t t t t I I I I m m m m a a a a g g g g e e e e W W W W i i i i t t t t h h h h U U U U R R R R L L L L : : : : ( ( ( ( N N N N S S S S U U U U R R R R L L L L ) ) ) ) u u u u r r r r l l l l ; p p p l l l a a a c c c e e e h h h o o o l l l d d d e e e r r r I I I m m m a a a g g g e e e : : : ( ( ( U U U I I I I I I m m m a a a g g g e e e ) ) ) p p p l l l a a a c c c e e e h h h o o o l l l d d d e e e r r r ; o o p p t t i i o o n n s s : : ( ( S S D D W W e e b b I I m m a a g g e e O O p p t t i i o o n n s s ) ) o o p p t t i i o o n n s s ; p r o g r e s s : ( S D W e b I m a g e D o w n l o a d e r P r o g r e s s B l o c k ) p r o g r e s s B l o c k c o m p l e t e d : ( S D W e b I m a g e C o m p l e t i o n B l o c k ) c o m p l e t e d B l o c k ;

作为入口函数,在 sd_setImageWithURL 方法中采用了多种参数灵活搭配的同名方法。而内部实质,都在向最后一个 sd_setImageWithURL 传入参数最多的方法进行调用处理。可以清晰的梳理函数构造逻辑,减轻代码编写量。

###下载部分 整个下载管理器对于下载请求的管理都是放在downloadImageWithURL:options:progress:completed:方法里面来处理的,该方法调用了上面所提到的addProgressCallback:andCompletedBlock:forURL:createCallback:方法来将请求的信息存入管理器中,同时在创建回调的block中创建新的操作,配置之后将其放入downloadQueue操作队列中,最后方法返回新创建的操作。每个下载操作的超时时间可以通过downloadTimeout属性来设置,默认值为15秒。

其具体实现如下:

} ( / i / d [ } r s ] e < e ; t S l u D f N L [ i } r W S p I w f n e a M e F s b d 1 u 2 r 6 O e ( o I d . t . a . l w [ w p m P a t f s w s e a r b i . e s e r g o l o c d l e l a e g e S n o f l f t O r U D m i [ } w . f . i p e R W = S p 4 f s f S i n e . l o e s L e D i l . s o D f l x l a n r s R b [ f W f e f ( e r W o e a s ; a C e I [ o e t i f l e ( a c s t t a ( q m w r b ( e n i f ( b c d u t A i l N u a s I c d i n N I a Q t A d o l o S e g e ( m a : s i r S m l d u i d d n b p U s e l 3 N a l ^ h s e D a l o e o d e > a t R t D f . S g l ( c e h m i g b w u n e d ) c i L o . D e b U a d e o c e a n e O d O d k o C * w o i D a I l d v t D c l r O p o : n a r n p c o c I l Y ) e i o k o a d p e w p s c e l e t w k m b E C o w ) a d e e r n r h q o r i n ) a a S { a n n d d r r a l o e u a a o l g c l a l c Q O a t o g e d t c n o c e k l r o a u p = t i a r + s e i a a a a s b y a l e e = i o d e t r o p l r d l * F a d l u r o n I s S O n r l y e l i o u c * e b e a S n m s D = p C o b r b m r r k c r a t D = a B I e l g a * P a a U l s a C c i W a g l m [ r a r c c r c g R F l o k o e d o e o a [ a s e k a o k e L o l m ( n b d p W c g N t s s s l g ( , r b p i : I D e i k e S i s F l r r U a l m o m e r t C M o a : o b e e N R c e a p a p a h a a u n l ^ r a s c S L k t g e g e t U n c t l ( U c s e D U : s e e r e n i R d h a o N R k B i a R u d , a D d o L C e b c S L s l v t L U r i B t o e n : o ) l ] I o e a R l n l d i w n ; ( m e n i c d L ] o a o n c N p U i t n k S * C ; c c t n l y S l R n e i d a a k a ] o : U e L i g U c c z a l l , ; a o R t R t e R a a e t l l c d p L e e W r L l l , a b b a e e e d q i l l , a a l r r r B u t r b b e c c l r } c } L a ) l e h e a a x } N k k b o a / ] I t u o s R o c c c p S s s a r n / ; F i r c t e p e k k e E F c , c O o l k q t i s c r o k } e 5 S i [ E n : a u i v F = t } r r f l . D f s x ] o c l e o e o e o U = i l W s e ; p o l s n d r c d r R n e e ( e c t m o t s S U a S L c i d b ! l u i p c : : i R l i * ) a s : I s f t o l ] r o z L l z e l h ^ m s i n e e p e ) b e r { l e { a e r o s t i q t , a ) r b d g l e n : e n u i { c ; o a ) u e f m O ( d i e o N k r c ; r D ) o r S B t s n S s , k l o v d D l W t s I [ s w r e e W o i n k B [ n e C r e c t t P O k l t a ) b k h e r O C o u l I U g o L o a r l { m f R e g m d n b a o L r r f p e ; a g r : e i l r c e U u e s n e U k D R r x s i t R * s o L l p C s e L s F w : e a h d C s o n u c c l e C a e r l r a t l d a l l U o l c e b ) l l f R a h d a l b L d c e S c { b a = : e r P i k a c u r e o z K c k w r O a l e e k s s l p t i ) y K e ] t e c ] e l ; i C y { ; y f o a : ] ; n l ( ; s l o ) b p o a t p c i t k o i : n o ^ s n { s & p S r D o W g e r b e I s m s a : g ( e S D D o W w e n b l I o m a a d g e e r D U o s w e n N l S o U a R d L e C r a P c r h o e g r ? e s N s S B U l R o L c R k e ) q p u r e o s g t r U e s s e s P B r l o o t c o k c o c l o C m a p c l h e e t P e o d l : i ( c S y D W : e b N I S m U a R g L e R D e o q w u n e l s o t a R d e e l r o C a o d m I p g l n e o t r e i d n B g l L o o c c k a ) l c C o a m c p h l e e D t a e t d a B ) l o t c i k m e { o u t I n t e r v a l : t i m e o u t I n t e r v a l ] ;

###缓存部分 为了减少网络流量的消耗,我们都希望下载下来的图片缓存到本地,下次再去获取同一张图片时,可以直接从本地获取,而不再从远程服务器获取。这样做的另一个好处是提升了用户体验,用户第二次查看同一幅图片时,能快速从本地获取图片直接呈现给用户。

SDWebImage提供了对图片缓存的支持,而该功能是由SDImageCache类来完成的。该类负责处理内存缓存及一个可选的磁盘缓存。其中磁盘缓存的写操作是异步的,这样就不会对UI操作造成影响。

# # # } i e e f l n s d o [ i T e i } i s f A f d e R ) 1 l ( G s . f t d E } t . i T ) o m D s _ ; r e i 2 p O e m s . a N i S } i } I C k t S f _ f m a ) c D I a c h a ( P 4 ( g h { _ t i H B i } i } e } d . d i } [ e e a a m O O f f l a a f _ : s a N O s t t f ( N s y * g E 3 L ( ( e a a ( i U S e n d e . i [ i i d d ) ! [ l I C t c a m i i m m a { a = [ _ e I a O ( t & a m m a a t t { _ f M m c b s a & g a a g g a a [ f i a a h j e e g g e e N i l n g e e l = ( D e e I I = = S l e a e c f r a I D s s B e M g t . i e t s a P P U U i M a e : i m c a P t n n I I t a n r ) i o a a P n a g g I I m n a i m Q g l N n g ) m m a a g c m a u e c G i l = a a p g e r a g e D u l = e { g g I e r e g e u a l n I e e m r a e e t a J Y g m P J a c t f , a t P E t a N P g f r e r o ; e E S h g G E e i e F e r ^ G ; ] e R G R l a i c K { D e R e e t l a e i P > a p e p E e e l y o N = t r p x D A c : Q ! G a e r r i i t u k u d P [ H s e e s r P l e e a N k a e s p t e a a y u t G P s n e r s c t t e a N P t n e A t h e c ) G N a t s t o : F o ) S G t a e P r [ r s i P i t n a y s o t { g r o i t t A e m : n e n o a h t l I i a f ( n t : P f m m P t f i ( i _ a a a N u i m i o d t d g g G r x a m n i h e e e e ( g a O s : f : . D i e g f k _ a ( s a m ) e I C d u B i t a ; , m a i l O z P a g a c s t O e N e ( g h k C L . G l D C e e C a ) h e a G R P a c r e n t F e a c h e i g a l p t h e c g t ) o s h e P a h 8 h ; a I ] P a l t ] t n ) a t c ) ) A t h u 1 r { h F l { . r o a i 0 a w r t m ) y i K e a ; : t e g i h y i e m I : m . a n k a s g t e g i 1 e e y e z 3 . r ] D e 7 r m a . e e c t w 8 p d o a i 0 r i n : d e a t ( t 7 s t e N h 8 e e n S n D t D 7 t i s a 1 a r : t i t e d a m 1 i c a a 3 o t t g n o a ) e 1 s r i . 0 i a m s u e t a c 2 s s t g a 6 i : r e l n Y i D e 1 g E b a 0 T S u t y t a p a e i e t s f m : t : o a r n r g N i i K e S b l e . J u ] y s P t ; : c E e ( a G s N l F : S e i n S ] l i t ; e l r T i y e n p r g e r o p r ) r : k o N e p U y e L r L t t ] o i ; D e i s s : k n : i ( l B ] O ; O L ) t o D i s k {

缓存到了本地,怎么查找缓存呢?代码如下:

} ( N S U i } N d } r O I f S i ) e p I O s ; t e 1 m ( 2 p p u r . a i d r . e a i } @ } r a g m o e r t f a n t e a n t a c u i g e u t h t o o * e B r i _ o r o U i } d } p n i ) l n o a p e r I f i ) e m o n s e t e I s ; r a { c n y r u l m ( p a ) g k i n a r e a d C [ a d t q e ( l o c t n a g i G s t o i u i ; p ( i ; s e s F e c n o e = m e s o e k l l h e n r a r e n p * I o f _ B ; y [ g a l . o d m a . a l D s e t f i o i a t m s o i e , i . s l s g e y c s l o i C k e c m n k k f S n o a { I ) o C c ( C D Q n m s a ( d a i I = u c a { t c d i c m m e e g h i s h a a [ u l e = e s k e d g g N e l p I F o e e S , e = d s a m o n F C O d i e t a r e r a p ^ ) [ s t c g K B o c e { s k O h e e l m h r { e I b _ , y o D e a l m j g : c i T t f a e e S ( k s y i g c t D N k p o d e t _ I S C e n i . : m m S a M s s d a a t c e n k i i i g r h m e I z s n e i e o d w m e k _ C n F r o ] a . I q a g o y n ; g h m u c r ) e e e a e h K ; B F i g u e ) e l o g e e T k y o r h ( y e : c K t f ) p y k k e o , e e y r D d y : K ^ i o ] k d e { s n ; e i y k e y s : ) : ] k k ; ( ; I e S m y D a W g c e e o b . s I s t m i : a z c g e o e . s Q w t u i ] e d ; r t y h C o m p d l i e s t k e I d m B a l g o e c . k s ) c d a o l n e e B l o d c i k s k { I m a g e . s c a l e ;

而部分清理则是根据我们设定的一些参数值来移除一些文件,这里主要有两个指标:文件的缓存有效期及最大缓存空间大小。文件的缓存有效期可以通过maxCacheAge属性来设置,默认是1周的时间。如果文件的缓存时间超过这个时间值,则将其移除。而最大缓存空间大小是通过maxCacheSize属性来设置的,如果所有缓存文件的总大小超过这一大小,则会按照文件最后修改时间的逆序,以每次一半的递归来移除那些过早的文件,直到缓存的实际大小小于我们设置的最大使用空间。清理的操作在-cleanDiskWithCompletionBlock:方法中,其实现如下:

} o d } i i ) d s ; ) p c a N N N N N N N f } f } i } } l t S S S S S S S o o f e c U A D D M U M r r a h R r 1 i a u I 2 u 6 ( n _ L r . r t t n . t ( N i } N i } N c [ ( [ . s c N f } d } D a a e e a t a N S f S f S u c N _ e o S o i ) i s * y c b e b S D D N r a S f l n A r s ; s y d t * l g l U i 3 ( 4 a ( 5 u r c U i f 7 s 8 r 9 p k n i * o e e e e R c . [ c . t [ [ c . m e h R l . . t . r . ( i } a c W c s r r x D r A L t r o e [ u o b n e L e m a N f t o i ( k e y p i r i e n m r n e t F M a N y S c m t s C s E i c c r * o s t * o l t r C i * a x S U ( h p h e a o n r t u a f n o i m d s i a l f n C U * R [ N N c i } _ l C l c u u a i r y i a u n o i T n * c e i a a I s L _ S S u f a e o f h r m t o r l r r u d f o u t h s l g c n o f D N r s t m . e c e i n e * e y c e i i D e o e e e h t r * i i u r ( y i p i U e r o a n u U e ; f c e ; t S s U r e e t f l c m e c b n o l o R K a n r t r R * V i a l a i e R S g e i e t b n u r c n e Q L e t D y C l L r a c t e l z t L r i e d l M i e t r e i ( B t u y o a a s e l a i t A e O e z r F e a o r C r a f d l i e = s r t * c T i s u t o e l b i m e i U n n a e k i o o u e c h o n o e i n l + j n o d l R a a * c n ; ( s c n e [ = * a e D u s o D a o = e v > e e L g r t h t c p k B , N f = c S e f r [ n a d c c u e s s e y o e C o a ( l S @ i h i l i c N D t d a [ t r I 0 i i r t S a m t ) o ^ U [ l [ e z e l e S a e O t t : l t r = n * a i c p c ; c { R N e N F e t e V U t b e o r s e & e r r l z h l h k L S E S i e E a R e l j d t e T m & d [ s e e A e e e _ : U n D l = n l L a e S a s o A C c o m s l S t g ( f R u a e = u u I = t c i l o D t c a a r o o l - i i e S i L m t s 0 m e s e t z A u e U u c c t v u o = z o t D l I e e ; [ e s D r r : e l r l R r h h e e r c e n _ W e s r = [ r i e D f l c e L r e e d I c a [ B m e U D a d N a = r s a i = o e t : e S F F t e t t < l a b R i t a [ S t e o t l c V e f n i i i e V e o o i I L r o t N M o [ c u e e r a a ) i t z l l m a d t d c n m W e r e S u r f t r : U e t l l C e e e A l S a e k _ a i c W M t ) i o c e R s e u { e a s s t u i l s ) q g t t = i u a l r e x L o d e U c = ) U e z A i u e h o t t b { e y V p ] u S s R h k R s e l r { e N P r [ h a l U K a i ; r i L e s e { L l e u o a y _ T b e R e l r c z f S e y : = = o d e P t K f i l A L y u a e e o e i l s f c C ( a h e i i m e r ] e t V r r z f S i c r a a ) r : y l n e D r r s i a u K r e . o l a e t c , a s , e c I i a e b [ o l n e o m r e c s e h m e M l n c y s o N n u s y r > a t U h o d e ^ s l N a u t t o o S D e i : : x e R e u S S { B f S n d e i a u l U a s g f n s C d L F r i i l . U a i r o l r V R t [ n i i e a B i c z z o d R g n v n l c a L e N e l l l c y e l e e e c i L e g a a o e l C ] S d e ] f h V r e V ) k s C r P l r c V u o U I U ; . e a u } r s a u ) k o r S y ] a e n i R n R m S l s ] o [ l n { c C n e o i l ] t s L t L a i u i ; r f u s o a t n p n d i u ) e E T e ] x z e n : i e i m c e u e c i n e n q o g ; C e W g r n l s g p h n m r e e c i s { t u t e a i C e i e [ n l e t e t r N t t F M a a r c / t o t l U N e e P M r i r o i ] o o l l V h h m u ] R S d t a o a e o w o ; r d T F a e 2 O p r ) L U I i t d t s r : n K i o i l S ; p a n ] R n o h i o F o H - a e f D l u i t r { ; L t n f r o p a s r y i a e e z i a [ T e B i i A r t n e y s c t A ] e o t o o g l s c t K i d l ] : a e l ; ) n o b t e o D a U e o l f ; r t : l s r j a r c i t R y n e . e i e o { : : 1 l V k r i L s s r m s o x c N ^ [ F a e o : : : : a o n p a S N N i l { c n d r N N x u D i t S S S l u t D i e S U C r a r e o C U e e o a s s D L a c t a d r o R A ] r t k o i L c e e t S t m L l ; y e C u r ] h K K i i C p C l : K a r e ; e e e o z o a o o Y e c c c A y y n e n r n c E y h e t g s ] D K c i t a S , e K o e ; a e u s e t ] U e r ] e t y r o n e ; N R y y ; r e ] r n t d S L s E r ] ; e R M S U n o ) n e o i R u r t s d z L m : { u i e T e N l f K o r U t i e t a L ( c y a t L i a ] l i ] d t ; F o ; i i n o o l S b n e k j D A i 1 a l p , t l s e o H i K c i d e a d y t d o ] e e b d n j c S F 2 o i i ) m z l p e e { a K s r e e y : ] o ; b j 2 [ N S U R L C o n t e n t M o d i f i c a t i o n D a t e K e y ] ] ;

###总结 1.把图片的解码工作放到子线程(SDWebImageDecoder)。 2.在主线程中完成重采样的工作。重采样算法一般有: Nearest Neighbour Resampling (最邻近重采样)、 Bilinear Resampling(双线性/两次线性重采样)、Bicubic Resampling (双立方/两次立方重采样)等。 3.利用空间换时间的做法,在子线程中解码图片并缓存位图结果,避免图片的重复解码,提升图片展示性能。如果列表中需要展示很多网络图片,SDWebImage这种做法,有利于提高列表的流畅度。 4.SDWebImage中下载的图片,即使解码缩放(decodedAndScaledDownImageWithImage:)后,图片大小未必和imageView的大小相同,这会引发重采样,我们可以在图片显示前,将图片裁剪成和imageView的大小相同,提升性能(一个小的优化点)。