iOS-關(guān)于鏈表與歷史追溯功能的探討

眾所周知,在面試的時候Runtime、數(shù)據(jù)結(jié)構(gòu)等等都是面試常問的題目部脚,當(dāng)然,不少朋友會吐槽面試問題常常脫離實(shí)際開發(fā)裤纹,畢竟那些只有一兩人兩三人組成的小開發(fā)組的項(xiàng)目委刘,整個項(xiàng)目往往只有一兩次使用到Runtime的機(jī)會丧没,甚至有的項(xiàng)目根本就是從頭到尾都沒用到過。
當(dāng)然嘛锡移,就算沒用到過呕童,但這方面的知識儲備還是需要的,不然面試根本就沒啥問題好問淆珊,全都是UI層次夺饲、業(yè)務(wù)邏輯的問題,別說面試官施符,面試者都可能會覺得蛋疼的緊吧往声?
話題扯遠(yuǎn)了,言歸正傳戳吝,Runtime還有使用到的機(jī)會浩销,那么鏈表這一概念在移動端開發(fā)到底會在什么時候被應(yīng)用到呢?在廁所中沉思的時候我突然想到這個問題听哭,移動端開發(fā)到底有什么功能開發(fā)會使用到鏈表的概念慢洋,非鏈表不能,又或者是使用鏈表會達(dá)到最好效果的呢陆盘?
身體放空的同時心靈也得到了升華普筹,我終于想到了一個可能性,那就是Web的歷史追溯礁遣。
在PC使用谷歌瀏覽器的時候在一次偶然的巧合下我發(fā)現(xiàn)了谷歌瀏覽器讓人眼前一亮的功能斑芜,具體模擬使用場景是這樣的:

1、松鼠癥的我堆積了大量的標(biāo)簽頁祟霍,其中一些標(biāo)簽頁是有下一級的Web鏈接及上一級的Web鏈接
2杏头、不小心錯誤關(guān)閉了其中一個標(biāo)簽頁,那個標(biāo)簽頁是我找了很久的資料沸呐,標(biāo)簽頁的前進(jìn)跟后退都是同一個網(wǎng)站的重要資料
3醇王、通過谷歌瀏覽器的打開最近關(guān)閉的標(biāo)簽頁我重新打開了標(biāo)簽頁,并且崭添,上一級的Web鏈接以及下一級的Web鏈接依然存在寓娩。

這是很棒的功能,讓人眼前一亮呼渣,而遺憾的是手機(jī)上的瀏覽器大多沒有這樣的功能(至少我日常使用的都沒見到)棘伴,那么作為一個開發(fā)者,我們要如何將這樣的功能挪移到手機(jī)上呢屁置?
我想到了鏈表焊夸,Web一級一級的連接方式無疑是鏈表的最佳詮釋,當(dāng)頁面被關(guān)閉時將完成的鏈表保存下來蓝角,當(dāng)頁面被從新打開時從鏈表讀取數(shù)據(jù)似乎是很好的解決辦法阱穗。
為了佐證我的想法饭冬,首先先寫一個Web Demo.

        let web = WKWebView(frame: CGRect.zero)
        web.navigationDelegate = self
        view.addSubview(web)
class ViewController: UIViewController,WKNavigationDelegate {
    ......
//實(shí)現(xiàn)代理方法來獲取URL地址,亦可通過監(jiān)聽Loading狀態(tài)揪阶,這些都隨便昌抠,需要注意的是,度娘會做相關(guān)網(wǎng)址轉(zhuǎn)譯鲁僚,這些轉(zhuǎn)譯需要根據(jù)自己選是否篩選炊苫。
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        print(navigationAction.request.url?.absoluteString)
        decisionHandler(WKNavigationActionPolicy.allow)
    }
}

   func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        print(navigationResponse.response.url)
        decisionHandler(WKNavigationResponsePolicy.allow)
        
    }

   func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print(webView.url)
    }

public class ListNode {
//商業(yè)項(xiàng)目中我們不應(yīng)該直接添加URLString,而是一個完整的數(shù)據(jù)模型冰沙,不過在此劝评,我們簡化一些操作。
    public var url: String
    public var next: ListNode?
    public init(_ url: String) {
        self.url = url
        self.next = nil
    }
}
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        let node = ListNode(webView.url!.absoluteString )
        if let l = list {
            node.next = l
            list = node
        } else {
            list = node
        }
    }


如此倦淀,我們便獲得了一個完整的鏈表蒋畜,里面記錄了標(biāo)簽頁從新建之始記錄的所有URL地址,并且撞叽,這是從尾到頭的姻成,若想要進(jìn)行歷史回溯便一層一層地將list.next中的url數(shù)據(jù)取出即可。

   func goBack() {
        let urlString = list?.next?.url ?? ""
        list = list?.next
        let request = URLRequest(url: URL(string: urlString)!)
        web?.load(request)
    }

但是這樣在實(shí)際使用上是會出很大問題的愿棋,首先是每次歷史回溯都將數(shù)據(jù)替代了科展,要是想回到原先的界面就只能使用WebView的goBack API,原本是最尾末的頁面但因?yàn)殛P(guān)閉而重新打開卻成了最初始的,這樣很容易造成業(yè)務(wù)邏輯上的混亂糠雨。
其二才睹,如果是同時具有上一級以及下一級URL(即不處于鏈表的首末尾)的Web,這樣的邏輯并不能使得Web goForward,功能并沒有完全實(shí)現(xiàn)甘邀。
除此之外還有等等問題在實(shí)際項(xiàng)目會有很多不同之處琅攘,需要一一調(diào)整。

在此松邪,我認(rèn)為可以這么設(shè)計(jì)坞琴,一個鏈表不夠就再加一個,兩個鏈表分別代表當(dāng)前頁面之前的數(shù)據(jù)以及這個頁面之后的數(shù)據(jù)逗抑,當(dāng)前頁面可以選擇性地放在兩個鏈表的首末剧辐。

        //當(dāng)頁面處于正常狀態(tài)而非是被打開的最近關(guān)閉標(biāo)簽頁時按正常流程走
        //當(dāng)頁面處于正常狀態(tài)而調(diào)用webView的goBack API 及 goForward API時改動雙鏈表
        //當(dāng)調(diào)用goBack API 時,將goBack之前的頁面從before List刪除邮府,添加到 after List荧关,并成為after List的 First Node.
        //當(dāng)調(diào)用goForward API 時,逆轉(zhuǎn)而使
        //如此褂傀,確保雙鏈表模擬的完整鏈表的正確性以及當(dāng)前頁面的url在完整鏈表中位置的正確性
        //當(dāng)頁面是最近被關(guān)閉的標(biāo)簽頁時檢查頁面的雙鏈表忍啤,確定頁面的url在鏈表中的位置
        //根據(jù)鏈表是否有值判斷當(dāng)前頁面是否存在上一級的頁面或者下一級的頁面
        //同樣的,根據(jù)調(diào)用的API對雙鏈表做出修正紊服。
    ......
    //雙鏈表
    var before:ListNode?  //當(dāng)前網(wǎng)頁之前的鏈表數(shù)據(jù),當(dāng)前網(wǎng)頁處于鏈表頭部
    var after:ListNode?   //當(dāng)前網(wǎng)頁之后的鏈表數(shù)據(jù)

//監(jiān)聽按鈕點(diǎn)擊以挪移鏈表
@IBAction func goBack(_ sender: AnyObject) {
   if web!.canGoBack {
            if let b = before {
                let node = b
                before = b.next
                if let a = after {
                    node.next = a
                }
                after = node
            }
        } else {
            
        }
    }
@IBAction func goForward(_ sender: AnyObject) {
       if web!.canGoForward {
            if let a = after {
                let node = a
                after = a.next
                if let b = before {
                    node.next = b
                }
                before = node
            }
        } else {
            
        }
    }

如此在正常狀態(tài)不斷挪移鏈表檀轨,在最近關(guān)閉的標(biāo)簽頁中獲取數(shù)據(jù)時方能獲取到正確數(shù)據(jù)。
目前正在寫一個完整的Web項(xiàng)目以正確模擬商業(yè)項(xiàng)目如此使用可能會出現(xiàn)的問題欺嗤,所以本文僅是探討如此的功能實(shí)現(xiàn)参萄,不能避免邏輯上可能存在的問題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末煎饼,一起剝皮案震驚了整個濱河市讹挎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吆玖,老刑警劉巖筒溃,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異沾乘,居然都是意外死亡怜奖,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進(jìn)店門翅阵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歪玲,“玉大人,你說我怎么就攤上這事掷匠±谋溃” “怎么了?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵讹语,是天一觀的道長钙皮。 經(jīng)常有香客問我,道長顽决,這世上最難降的妖魔是什么短条? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮才菠,結(jié)果婚禮上慌烧,老公的妹妹穿的比我還像新娘。我一直安慰自己鸠儿,他們只是感情好屹蚊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著进每,像睡著了一般汹粤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上田晚,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天嘱兼,我揣著相機(jī)與錄音,去河邊找鬼贤徒。 笑死芹壕,一個胖子當(dāng)著我的面吹牛汇四,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播踢涌,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼通孽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了睁壁?” 一聲冷哼從身側(cè)響起背苦,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎潘明,沒想到半個月后行剂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钳降,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年厚宰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片遂填。...
    茶點(diǎn)故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡固阁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出城菊,到底是詐尸還是另有隱情备燃,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布凌唬,位于F島的核電站并齐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏客税。R本人自食惡果不足惜况褪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望更耻。 院中可真熱鬧测垛,春花似錦、人聲如沸秧均。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽目胡。三九已至锯七,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間誉己,已是汗流浹背眉尸。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人噪猾。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓霉祸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親袱蜡。 傳聞我的和親對象是個殘疾皇子丝蹭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,085評論 25 707
  • (10/100) 此文章引用的部分均出自目標(biāo)達(dá)成專家、幸福進(jìn)化俱樂部創(chuàng)始人,易仁永澄老師公眾號戒劫。自我管理系統(tǒng)重啟初...
    xiaolubobo閱讀 169評論 0 0
  • 什么是Thunk函數(shù) 本段內(nèi)容無恥抄襲自阮一峰的《ESMAScript 6 入門》中對Thunk函數(shù)的介紹 Thu...
    pure懶人閱讀 1,130評論 0 2
  • UITableView中將分割線樣式改為None tableView.separatorStyle = UITab...
    張群閱讀 2,553評論 1 6
  • 第23周話題,讓我們思考人生對與錯婆廊。 個人覺得迅细,人生沒有對錯,每一種選擇都代表一種不同的人生淘邻,選擇的適合與否是來自...
    Natsuka閱讀 256評論 2 2