Swift 进阶笔记-业务化 Tips(1)-哈希

本主题旨在自己学习的过程中举出实例业务项目片段帮助自己提高灵性,深入领会知识概念,记作学习拓展笔记。希望在有幸被您看到文章的同时为您带来更多启示。

Hashable

如果我们想要将自定义结构体、类储存在 Set 中,或是将其作为 Dictionary 的键值 Key,可以继承 Hashable 并实现需要实现的内容。
例如实现:自定义多选 UI,选出去过的城市,将选中的城市存储在集合中。


效果.gif

先上Demo:
https://github.com/wiiale/AdvancedSwiftThinker/tree/master/T01-Hashable-Footprint

这里为了保持简单,直接tableView.reloadData()了,也可以添加漂亮的 UI、动画效果来自定义的更加明显。

实现代码中主要与 Hasable 相关模块

实现
// City.swift

struct City {
    let name: String
    let province: String
}

extension City: Hashable {
    var hashValue: Int {
        get {
            return "\(name)\(province)".hashValue
        }
    }
    
    static func ==(lhs: City, rhs: City) -> Bool {
        return lhs.name == rhs.name
    }
}
使用

Set<City>: City 需要实现Hashable才能存储在集合 Set 中。

// TableViewDataSource.swift
import UIKit

class TableViewControllerDataSource: NSObject, UITableViewDataSource {
    var cities: [City]
    // Set<City>
    var selectedCitiesSet: Set<City>
    weak var owner: TableViewController?
    
    init(cities: [City], selectedCitiesSet: Set<City>, owner: TableViewController?) {
        self.cities = cities
        self.selectedCitiesSet = selectedCitiesSet
        self.owner = owner
    }

    ···
}

状态改变时,是否相等的比较避免不必要的状态更新,同时用到了实现 Hashable 时需要实现 Equatable 的重载==操作符来进行判等操作。对于元素类型实现了 Equatable 协议的数组,也可以直接使用contains方法会查看数组是否包含满足给定的谓词条件的元素等操作。

TableViewController.swift
func stateDidChanged(state: State, previousState: State?, command: Command?) {
    if let command = command, case .loadCities(let handler) = command {
        CityStore.shared.getCities(completionHandler: handler)
    }
    
    // 判等
    if previousState == nil
        || previousState!.dataSource.cities != state.dataSource.cities
        || previousState!.dataSource.selectedCitiesSet != state.dataSource.selectedCitiesSet
    {
        tableView.dataSource = state.dataSource
        tableView.reloadData()
    }
}
注意点(1)-避免哈希碰撞

如果用不太稳妥的方式实现 hashValue 则会导致哈希碰撞,需要注意 hashValue 的实现方式。错误示例:

var hashValue: Int {
    get {
        return name.hashValue ^ province.hashValue
    }
}
City(name: "Shanghai", province: "Shanghai").hashValue // 0
City(name: "Beijing",  province: "Beijing") .hashValue // 0
City(name: "Hangzhou", province: "Zhejiang").hashValue // 6535861917244346740
City(name: "Zhejiang", province: "Hangzhou").hashValue // 6535861917244346740
注意点(2)-继承 NSObject 的类

NSObject 已继承 Equatable, Hashable,存在方法 isEqual,不需要重载==运算符。

class CityObj: NSObject { ··· }
extension CityObj {
    override var hashValue: Int {
        get {
            return "\(name)\(province)".hashValue
        }
    }
    
    override func isEqual(_ object: Any?) -> Bool {
        return name == (object as? CityObj)?.name
    }
}

本文 ViewController 学习并尝试单向数据流动的方式编写,参考自喵神的单向数据流动的函数式 View Controller

文章Demo 汇总:
https://github.com/wiiale/AdvancedSwiftThinker

本册文集中以“提出简单需求->简单实现需求片段”为流程,内容只针对该知识点实现的业务实例进行熟悉,业务也必定存在比文章方法更好的实现方式,文章旨在分析知识点并加深理解。文集不普及基本知识,不包含《Swift 进阶》书籍的详细内容。深入学习Swift请大家支持正版书籍(ObjC 中国)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351