国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

大神推薦的頭像緩存策略

移動(dòng)開(kāi)發(fā) Android
頭像的原始圖片可能有各種尺寸,但在 App 里,我們很可能需要某種固定樣式的頭像,例如正方形或者圓形。如果我們使用通用的圖片緩存工具如 SDWebImage、Kingfisher 等,那么還需要自己做圖片的裁剪和加工。如果直接用 UIImageView 來(lái)縮小,圖片細(xì)節(jié)就會(huì)變得過(guò)于“銳利”,影響觀看。

[[151245]]

許多 App 都有用戶系統(tǒng),不論是自己實(shí)現(xiàn)還是使用第三方,大概都需要顯示用戶的頭像。比較常見(jiàn)的情景下,頭像會(huì)在某些列表里出現(xiàn),例如聯(lián)系人列表、消息列表等。

雖然頭像也是圖像,但相比于普通圖片,我們對(duì)頭像有更高的要求。

頭像的原始圖片可能有各種尺寸,但在 App 里,我們很可能需要某種固定樣式的頭像,例如正方形或者圓形。如果我們使用通用的圖片緩存工具如 SDWebImage、Kingfisher 等,那么還需要自己做圖片的裁剪和加工。如果直接用 UIImageView 來(lái)縮小,圖片細(xì)節(jié)就會(huì)變得過(guò)于“銳利”,影響觀看。

進(jìn)一步,一個(gè) App 里可能不只有一種頭像樣式。比如某些場(chǎng)景里要有大頭像,某些要用小頭像,某些要用原始尺寸的頭像;或者某些場(chǎng)景里要用正方形頭像,某些場(chǎng)景里要用圓角矩形頭像,不一而足。注意:?jiǎn)渭冇?layer.cornerRadius 或 CALayer 來(lái) mask 都會(huì)導(dǎo)致列表的滑動(dòng)性能問(wèn)題,因此不考慮。

如果要做優(yōu)化,我們當(dāng)然希望這些不同樣式的小頭像能夠存儲(chǔ)在本地,不用再?gòu)木W(wǎng)絡(luò)獲取再裁減或處理樣式。一來(lái)減少不需要的流量消耗,二來(lái)提高頭像載入速度,用戶體驗(yàn)自然會(huì)更好。

基于上述分析,我們來(lái)設(shè)計(jì)一個(gè)頭像緩存系統(tǒng)。它的目標(biāo)是快速地獲取并緩存有樣式的頭像圖片,并能比較容易地集成到已有項(xiàng)目中。

一些前提:

頭像的圖片 URL 唯一,即不同的頭像有不同的 URL。如果用戶換了頭像,那么新頭像 URL 和舊的不一樣;
頭像是公開(kāi)資源,不需要做驗(yàn)證即可下載。

好了,我們來(lái)做一做思維游戲。

首先,已有的用戶模型可能為:

 

  1. struct User { 
  2.  
  3. let userID: String 
  4. let username: String 
  5. let avatarURLString: String 
  6. //... 

 

其中 avatarURLString 表示遠(yuǎn)端的頭像鏈接。如果我們要下載它,最簡(jiǎn)單的話,直接用 NSData 的一個(gè)構(gòu)造方法即可:

 

  1. if let 
  2. URL = NSURL(string: avatarURLString), 
  3. data = NSData(contentsOfURL: URL), 
  4. image = UIImage(data: data) { 
  5. // TODO 

假如某個(gè)列表里有 5 個(gè)條目都是同一個(gè)用戶產(chǎn)生的,那這個(gè)用戶的頭像要同時(shí)顯示 5 次,我們難道要下載 5 次嗎?

為了解決這個(gè)問(wèn)題,我們可以將獲取頭像這一行為當(dāng)作一個(gè)“請(qǐng)求”:

 

  1. typealias Completion = UIImage -> Void 
  2.  
  3. struct Request: Equatable { 
  4.  
  5. let avatarURLString: String 
  6. let completion: Completion 

 

我們可將請(qǐng)求用一個(gè)數(shù)組(即請(qǐng)求池)紀(jì)錄下來(lái):

 

  1. var requests: [Request] 

這樣,每次要下載某個(gè)頭像時(shí),構(gòu)造一個(gè)請(qǐng)求。先將其放入請(qǐng)求池,然后檢查請(qǐng)求池中包含此 avatarURLString 的請(qǐng)求的個(gè)數(shù),如果數(shù)量大于1,那說(shuō)明之前已經(jīng)有過(guò)同樣的請(qǐng)求,我們就不執(zhí)行下載的操作,靜靜等待***個(gè)請(qǐng)求的幫助。

Navi AvatarPod

過(guò)一會(huì)兒,之前的請(qǐng)求下載結(jié)束,那這時(shí)只需要執(zhí)行全部有同樣 avatarURLString 的請(qǐng)求的 completion,后一個(gè)(或幾個(gè))就“免費(fèi)”得到了服務(wù)。

Navi Completion

以上是初次需要下載的情況。若我們已經(jīng)下載了頭像圖片,我們依然可以構(gòu)造請(qǐng)求,只不過(guò)之后就不執(zhí)行下載操作,而是去文件系統(tǒng)里尋找而已。同理,我們的請(qǐng)求里可以包含樣式,假如同一個(gè)用戶的五個(gè)頭像有不同的樣式,我們只需要在***執(zhí)行每個(gè)請(qǐng)求的 completion 時(shí)再分別處理樣式。

既然下載后要保存,那怎么保存比較好呢?

有人傾向于直接用文件系統(tǒng)的 API 將數(shù)據(jù)存在文件系統(tǒng)里;有人已經(jīng)使用的 Core Data,那他會(huì)傾向于放在 Core Data 里,況且 Core Data 實(shí)體的某些屬性類型有 External 特性,勾選后,既不占用內(nèi)存空間,也免去了直接操作文件系統(tǒng)的繁瑣;還有人使用 Realm 或直接用 SQLite 等,反正都有類似的存儲(chǔ)過(guò)程,只不過(guò)細(xì)節(jié)不同。

我的建議是將原始圖片保存在文件系統(tǒng)中(或 Core Data 勾選 External),小的有樣式頭像可以直接以屬性保存在數(shù)據(jù)庫(kù)中(通常例如 Core Data 或 Realm 都支持 NSData 的屬性,但不能過(guò)大,因?yàn)樗鼈儠?huì)待在內(nèi)存里)。

可惜,如果現(xiàn)在我們要制作一個(gè)框架來(lái)緩存頭像,那我們就不可能非常具體地去幫用戶存儲(chǔ)文件。因?yàn)榧?xì)節(jié)千差萬(wàn)別,實(shí)在顧不過(guò)來(lái)。而且就算有了,用戶也很難集成這一步到已有代碼。若不考慮用戶的喜好,那我們實(shí)際上做出的是一個(gè)“通用”的圖片緩存系統(tǒng)。這里的通用以“不夠優(yōu)化”來(lái)理解。

好在,我們可以定義協(xié)議,在協(xié)議中聲明存儲(chǔ) API,用戶自行實(shí)現(xiàn)存儲(chǔ)過(guò)程。我們的緩存系統(tǒng)只需要調(diào)用 API 即可,不用關(guān)心存儲(chǔ)過(guò)程的細(xì)節(jié)。

再把頭像樣式考慮進(jìn)去,于是有:

 

  1. protocol Avatar { 
  2.  
  3. var URL: NSURL { get } 
  4. var style: AvatarStyle { get } 
  5. var placeholderImage: UIImage? { get } 
  6. var localOriginalImage: UIImage? { get } 
  7. var localStyledImage: UIImage? { get } 
  8.  
  9. func saveOriginalImage(originalImage: UIImage, styledImage: UIImage) 

 

稍微說(shuō)明一下:URL 自然表示頭像的原始鏈接;style 表示本次要顯示的頭像的樣式,稍微會(huì)進(jìn)一步討論;placeholderImage 很好理解,在顯示真正的頭像之前,需要一個(gè)占位符,不同的 App 有不同的設(shè)計(jì),所以也交給用戶;localOriginalImage 表示本地存儲(chǔ)的原始圖片,既然存儲(chǔ)已由用戶控制,那讀取自然由用戶控制;localStyledImage 表示本地有樣式的頭像,用戶可以根據(jù)樣式的不同來(lái)提供;***是saveOriginalImage(originalImage:styledImage:),由用戶控制存儲(chǔ)過(guò)程,包括原始圖片以及本次的樣式圖片。

其中,頭像樣式大概可以做成下面這樣:

 

  1. enum AvatarStyle: Equatable { 
  2.  
  3. case Original 
  4. case Rectangle(size: CGSize) 
  5. case RoundedRectangle(size: CGSize, cornerRadius: CGFloat, borderWidth: CGFloat) 
  6.  
  7. typealias Transform= UIImage -> UIImage? 
  8. case Free(name: String, transform: Transform) 

 

有原始樣式(不處理)、固定尺寸的矩形(可生成正方形等)、可帶透明邊的圓角矩形(可生產(chǎn)圓形等),以及一種自由樣式,由用戶自行提供圖片變換函數(shù)。看起來(lái)比較齊備,也可再增加。

然后我們?cè)俳o UIImageView 擴(kuò)展一個(gè)方法:

 

  1. extension UIImageView { 
  2.  
  3. func navi_setAvatar(avatar: Avatar) { 
  4. // TODO 

 

以方便用戶使用。***的圖解如下:

Navi 的緩存架構(gòu)

用戶有列表要顯示,列表?xiàng)l目包含頭像,于是構(gòu)造一個(gè) Avatar 的描述去 AvatarPod 中喚醒 Avatar。

AvatarPod 避免重復(fù)下載,并實(shí)現(xiàn)整個(gè)邏輯。比如先去內(nèi)存緩存中查詢,沒(méi)有就看看是否用戶提供了本地圖片,再?zèng)]有就去下載。下載好了就處理樣式,并將原圖和樣式圖交給用戶存儲(chǔ)。

那么在具體的集成上,用戶只需要讓其 User 實(shí)現(xiàn) Avatar 協(xié)議或者構(gòu)造一個(gè)新的“中間對(duì)象”,其包含 User 和 AvatarStyle,并讓此對(duì)象實(shí)現(xiàn) Avatar 協(xié)議。我推薦用中間對(duì)象的方式,這樣對(duì)已有代碼的修改會(huì)很少,而且更好支持多種樣式。

具體請(qǐng)看 Navi 的代碼以及 Demo。文件并不多,應(yīng)該能比較容易地看明白。不過(guò)運(yùn)行 Demo 需要 iOS 設(shè)備已在“設(shè)置”里登錄了 Twitter 帳戶,沒(méi)有 Twitter 帳號(hào)的同學(xué)可先去 twitter.com 注冊(cè)一個(gè)。

***,Navi 的名字來(lái)源于電影《阿凡達(dá)》里的納美人(Na'vi),為潘多拉星球上的智慧類人生物。人類到達(dá)后潘多拉后,利用基因改造合成了一種可以由人控制的類似那美人的生物,也就是 Avatar(意為化身或替身),以便更好地和原住的納美人交流。

原文鏈接: https://github.com/nixzhu/dev-blog

責(zé)任編輯:chenqingxiang
相關(guān)推薦

2022-05-10 08:58:56

CacheHTTP

2021-03-29 11:51:07

緩存儲(chǔ)存數(shù)據(jù)

2023-11-16 08:22:14

LruCacheAndroid

2023-05-04 16:10:13

緩存前端

2024-06-28 08:31:54

2019-03-20 09:11:50

Web緩存策略

2024-06-26 19:18:53

2018-10-24 14:30:30

緩存服務(wù)更新

2023-11-21 09:41:00

緩存策略存儲(chǔ)

2017-06-29 09:15:36

推薦算法策略

2018-09-17 14:34:34

微服務(wù)測(cè)試架構(gòu)

2024-02-29 08:00:00

Kernel-CF機(jī)器學(xué)習(xí)

2010-11-01 13:58:51

虛擬服務(wù)器

2013-10-16 16:58:17

iOS優(yōu)化緩存優(yōu)化

2024-11-11 06:20:00

緩存開(kāi)發(fā)

2023-11-06 07:33:01

推薦策略數(shù)據(jù)分析

2019-10-22 09:11:50

策略業(yè)務(wù)代碼

2018-10-23 10:47:03

高并發(fā)系統(tǒng)緩存

2024-03-14 08:57:04

高并發(fā)緩存更新

2025-02-03 00:00:35

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

欧亚精品一区| 欧美一区二区成人| 国产熟女高潮视频| 99免费精品在线观看| 国产福利视频在线播放| 亚洲色图在线看| 欧美男男同志| 欧美一区二区三区爱爱| 中文字幕在线免费观看视频| 亚洲天堂免费视频| 久久男人av| 国产精品9999久久久久仙踪林| 久久久蜜桃一区二区人| 免费毛片网站在线观看| 亚洲精品视频观看| 国产精品一卡二卡三卡| 永久免费看mv网站入口亚洲| 欧美激情网址| 国产精品一区二区你懂得| 久久99精品国产| 亚洲人辣妹窥探嘘嘘| 性做久久久久久免费观看欧美| 国产二区三区在线| 久久综合88中文色鬼| 99re6这里只有精品| 日本一区免费看| 国产成人在线视频免费播放| 91午夜国产| 精品国产免费人成电影在线观看四季| 电影一区中文字幕| 国产精成人品localhost| 成人性视频免费网站| 视频一区二区在线播放| 国产一区二区三区在线观看视频| 精品视频免费| 在线亚洲美日韩| 亚洲女同ⅹxx女同tv| av免费网站在线观看| 欧美国产第一页| 99香蕉国产精品偷在线观看 | 春日野结衣av| 91久久精品国产91性色tv| 唐人社导航福利精品| 国产日韩欧美日韩大片| 久久精品国产在热久久| 麻豆传媒在线播放| 伊人久久久久久久久久久| 欧美日韩国产免费观看| 国产真实乱子伦| 制服丝袜一区二区三区| 亚洲色图丝袜| 国产在线无码精品| 在线观看视频一区| 日韩高清三区| 精品无码国产一区二区三区av| 在线视频一区二区三区| 综合激情五月婷婷| japanese在线播放| 日韩一卡二卡三卡四卡| 亚洲天堂一区二区三区四区| www.亚洲高清| 中文字幕欧美日韩在线| 久久婷婷一区| 国产一二三区在线视频| 国产精品久久精品| 国产欧美日韩中文久久| 亚洲成av在线| 美女黄色片网站| 91精品国产福利在线观看 | 日韩高清不卡| 蜜桃999成人看片在线观看| 夜夜夜精品看看| 日韩中文字幕无砖| 韩日视频在线观看| 日韩电影在线观看中文字幕| 亚洲精品偷拍| 男人久久精品| 91精品中国老女人| 亚洲妇熟xx妇色黄| 最新国产一区| aaaaaaa大片免费看| 欧美美最猛性xxxxxx| 国产福利一区二区三区视频在线| 丝袜美腿av在线| 久久久福利视频| 欧美性猛交xxxxxx富婆| 亚洲欧美网站在线观看| 在线看黄网站| 91精品在线观看视频| 亚洲国产成人av网| 久久不见久久见免费视频7| 日韩一区二区三区不卡视频| 久久天天躁夜夜躁狠狠躁2022| 国产成人精品亚洲午夜麻豆| 俺来俺也去www色在线观看| 欧美精品成人一区二区在线观看| 精品视频在线看| 国内精品久久久久久久影视蜜臀 | 91精品福利在线一区二区三区| 欧美激情aⅴ一区二区三区| 中文字字幕在线中文乱码电影| 亚州精品天堂中文字幕| 国产精品丝袜久久久久久app| caoporn成人| 捆绑紧缚一区二区三区在线观看| 亚洲3p在线观看| 亚洲自拍另类综合| 欧美成人日韩| 日本欧美在线视频免费观看| 鲁丝一区二区三区免费| 日韩免费观看高清完整版 | 2021国产精品视频| 亚洲人成7777| 国产精品成人一区二区不卡| 国产在线视频你懂得| 久久99精品久久久久久青青日本 | 午夜久久电影网| 欧美 日韩 国产 一区| 亚洲免费视频一区二区三区| 视频一区二区三| 在线成人免费网站| 国产精品少妇自拍| 国产大片一区| 青草影视电视剧免费播放在线观看| 男人j进女人j| 久久久久亚洲精品国产| 亚洲一区二区三区四区在线| 亚洲午夜91| 精品国产第一福利网站| 免费一区二区三区在线观看| 成人免费午夜电影| 欧美成人精品福利| 99久久久国产精品| 久久中文亚洲字幕| 超碰在线中文字幕| 日日噜噜夜夜狠狠| 99精品99久久久久久宅男| 欧美成人女星排名| 久久青草国产手机看片福利盒子| 九九久久电影| 色呦呦在线资源| 999精品视频在线| 国产精品美女av| 日韩欧美的一区二区| 91捆绑美女网站| 欧美a级在线| 一二区成人影院电影网| 在线免费中文字幕| 丁香色欲久久久久久综合网| 国产精品一区二区电影| 日韩经典中文字幕在线观看| 亚洲最大的成人av| 麻豆国产精品视频| 国产精品一区二区av交换| 男女视频在线| 2018高清国产日本一道国产| 欧美三级华人主播| 久久免费少妇高潮久久精品99| 欧美日韩精品综合在线| 国产日产欧美一区| 亚洲免费网址| 日韩成人av在线资源| av手机在线观看| ga∨成人网| 精品少妇人欧美激情在线观看| 成人福利视频在线观看| 色诱女教师一区二区三区| 色久综合一二码| 中文字幕欧美日韩一区| 日本aⅴ精品一区二区三区| 国产在视频线精品视频www666| 欧美激情网站| 国产毛片在线看| 日本久久精品一区二区| 日韩亚洲视频| 成人久久18免费网站图片| 成人444kkkk在线观看| 日韩美女天天操| 亚洲制服丝袜一区| www成人在线观看| 久久精品国产久精国产爱| 中文字幕午夜精品一区二区三区| 精品一区二区三区中文字幕视频| 天堂аⅴ在线地址8| 97色伦图片97色伦在线电影| 国产精品97在线| 中文字幕剧情在线观看一区| 亚洲xxxx在线| 日韩av手机在线| 久久亚洲国产精品成人av秋霞| 日韩视频一区二区| 日韩欧美黄色动漫| 国产精品视频九色porn| jizz一区二区| 国产剧情在线观看一区二区| 国产亚洲毛片| 在线观看一区| 夜夜亚洲天天久久| 亚洲图片制服诱惑| 国产伦精品一区二区三区视频孕妇 |