iwatch是智能手表的一次革命。iwatch的應用也将會越來越多,基于watch的一些特點,watchos的開發者需要更加精益的把握watch的ui和性能。運用watchos自帶的緩存體系進行資料的緩存,是增強使用者體驗度的一種方式,這篇部落格,介紹在watchos中進行異步加載圖檔和緩存的方法,願與志同道合的朋友,一起交流。
在進行設計之前,我們應該先了解,watchos的緩存容量為最大20m,因為有限,我們更應該認真的利用每一份空間,是以,緩存我們不僅可以存,在即将裝滿的時候,我們還要有辦法從緩存中删去一些東西,讓出空間,那麼應該删除哪些東西了,我們應該都可以想到,當然是舊的了,把最早的緩存删掉,是以,在存的時候,我們要設計一種規則,可以儲存存入的時間,并且不影響我尋找這個緩存檔案。我的方法是通過格式化的命名:
<a href="http://my.oschina.net/u/2340880/blog/521527#">?</a>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<code>//這是一個規範緩存命名的方法</code>
<code>func checkstring(str:nsstring)->nsstring{</code>
<code> </code><code>let result:nsmutablestring=nsmutablestring()</code>
<code> </code><code>//先将所有的非字母和數字剔除掉</code>
<code> </code><code>for</code> <code>var i=0 ; i<str.length ; i++ {</code>
<code> </code><code>if</code> <code>(str.characteratindex(i)>=48&&str.characteratindex(i)<=57)||(str.characteratindex(i)>=65&&str.characteratindex(i)<=90)||(str.characteratindex(i)>=97&&str.characteratindex(i)<=122){</code>
<code> </code><code>result.appendformat(</code><code>"%c"</code><code>,str.characteratindex(i))</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code> </code><code>//拼接上目前時間戳</code>
<code> </code><code>let date:double = nsdate().timeintervalsince1970</code>
<code> </code><code>result.appendformat(</code><code>"?%.0f"</code><code>,date)</code>
<code> </code><code>return</code> <code>result</code>
<code>}</code>
通過?符号将名稱和時間戳進行了拼接。
這一步是如下的設計思路:通過圖檔url從緩存的路徑中進行尋找,如果有,直接取出圖檔,如果沒有,開啟一個線程進行異步加載,完成後重新整理主線程ui并将圖檔檔案規範命名後進行緩存:
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<code>//進行存取緩存的操作</code>
<code>//取出watchos的緩存目錄</code>
<code>let imagedic:nsdictionary = wkinterfacedevice().cachedimages as nsdictionary</code>
<code> </code><code>//取圖檔存儲的名稱</code>
<code> </code><code>let imageurl:nsmutablestring=nsmutablestring()</code>
<code> </code><code>//這裡的url是外界傳進來的圖檔位址url,進行去掉特殊字元</code>
<code> </code><code>for</code> <code>var i=0 ; i<url?.length ; i++ {</code>
<code> </code><code>if</code> <code>(url?.characteratindex(i)>=48&&url?.characteratindex(i)<=57)||(url?.characteratindex(i)>=65&&url?.characteratindex(i)<=90)||(url?.characteratindex(i)>=97&&url?.characteratindex(i)<=122){</code>
<code> </code><code>imageurl.appendformat(</code><code>"%c"</code><code>,(url?.characteratindex(i))!)</code>
<code> </code><code>}</code>
<code> </code><code>//查找緩存中是否有圖檔</code>
<code> </code><code>//周遊watchos的緩存目錄</code>
<code> </code><code>for</code> <code>var i=0 ; i<imagedic.allkeys.count ; i++ {</code>
<code> </code><code>//通過規定好的?進行分割</code>
<code> </code><code>let str:nsarray = imagedic.allkeys[i].componentsseparatedbystring(</code><code>"?"</code><code>)</code>
<code> </code><code>if</code> <code>str[0].isequaltostring(imageurl as string) {</code>
<code> </code><code>//找到圖檔 view是要設定的interfaceimage</code>
<code> </code><code>view.setimagenamed(imagedic.allkeys[i] as? string)</code>
<code> </code><code>return</code><code>;</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code> </code><code>//設定預設圖檔 這裡是外界傳進來的預設圖檔,如果需要下載下傳,先設定預設圖檔</code>
<code> </code><code>if</code> <code>defaultimage != nil {</code>
<code> </code><code>view.setimagenamed(defaultimage as? string)</code>
<code> </code>
<code> </code><code>//進行下載下傳和存儲</code>
<code> </code><code>let dispath = dispatch_get_global_queue(dispatch_queue_priority_high, 0)</code>
<code> </code><code>//在新的線程中下載下傳</code>
<code> </code><code>dispatch_async(dispath, { () -> void in</code>
<code> </code><code>let imgurl:nsurl = nsurl(string: url as! string)!</code>
<code> </code><code>let imagedata:nsdata? = nsdata(contentsofurl: imgurl)</code>
<code> </code><code>if</code> <code>imagedata != nil {</code>
<code> </code><code>//主線程中重新整理</code>
<code> </code><code>dispatch_async(dispatch_get_main_queue(), { () -> void in</code>
<code> </code><code>view.setimagedata(imagedata!)</code>
<code> </code><code>})</code>
<code> </code><code>//寫緩存 如果緩存滿了 就删掉時間戳最早的一張緩存</code>
<code> </code><code>//這個方法會傳回bool值,判斷是否存入成功</code>
<code> </code><code>while</code> <code>!wkinterfacedevice().addcachedimagewithdata(imagedata!, name: checkstring(url!) as string) {</code>
<code> </code><code>//如果存入失敗,删去時間戳最早的緩存</code>
<code> </code><code>var temp:nsstring?</code>
<code> </code><code>//儲存最早的緩存名稱</code>
<code> </code><code>var result:nsstring?</code>
<code> </code><code>for</code> <code>var i=0 ; i<imagedic.allkeys.count ; i++ {</code>
<code> </code><code>let str:nsarray = imagedic.allkeys[i].componentsseparatedbystring(</code><code>"?"</code><code>)</code>
<code> </code><code>if</code> <code>temp == nil {</code>
<code> </code><code>temp = str[1] as? nsstring</code>
<code> </code><code>result = imagedic.allkeys[i] as! string</code>
<code> </code><code>break</code>
<code> </code><code>}</code>
<code> </code><code>if</code> <code>str[1].doublevalue < temp?.doublevalue {</code>
<code> </code><code>//找到更早的緩存</code>
<code> </code><code>}</code>
<code> </code><code>//删掉緩存</code>
<code> </code><code>wkinterfacedevice().removecachedimagewithname(result as! string)</code>
<code> </code><code>}</code>
<code> </code><code>})</code>
上面的代碼和注釋,已經介紹了所有的思路,有錯誤之處或者更好的方式,還望多多指點。