关于Swift 你可能连变量都不会定义
写在开头
很多人说寒哥不写干货 那今天寒哥就狠狠心 写个 (其实不是不写 是太懒了 平时都写在印象笔记中 因为是给自己看的 格式比较散 要写博客 就要认认真真的写 怕误了看官的眼 )
- 顺便来个广告
iOS开发者 群532084214 给大家提供一个交流技术 也可以聊天打屁的平台
此文默认 读者有iOS开发经验 包括OC Swift 和一点点的runtime的理解
先新建个项目 Swift 和oc都行
新建一个OCClass:NSObject
我们来声明一个成员属性
Paste_Image.png Paste_Image.png
所有人都知道定义这都ivar的时候 系统会帮你做好几件事
生成带下划线的私有成员属性 对应 的setter 和getter
那么我们来Swift中看一下怎么定义一个成员变量
Paste_Image.pngso easy 这个谁不会嘛 (我这里不讨论可选类型 而是讨论 什么叫做存储变量 什么叫做计算变量)
我们会在想 Swift 会不会像oc一样 给我们同样的生成了 setter 和getter呢
于是有的人会这样写
然后这样调用
Paste_Image.png然后一运行程序 Crash了 很多人 会说 肯定了 不就是循环调用
断点出的堆栈信息 这样的
很明显 这就是循环调用了 但是你把self.去掉 之后再次运行
Paste_Image.png还是崩
奶奶的要崩溃了 这是什么鬼
其实Swift设计的初衷和oc并不是特别一样
后文解答
我们先来看一个mvc的结构图
Paste_Image.png Paste_Image.png其实在mvc中 View是不能拿到model的 他们互相不知道
但是在开发过程中 我们很多view的数据来源自model 如果我们在外部提供一个一个的属性 然后等着控制器 去赋值 再在对应的setter里面去 修改view 的显示 我们会发现很累 因为一个页面可能有太多属性 所以在大多数情况 我们在view声明一个model的属性 等值控制器去赋值
但是
但是
但是
重要的事情说三遍
我们这样我违反了 mvc的思想 其实(mvvm)也是这样的 view不能拿到model 因为你拿到了model 就可以修改 就会造成页面中的数据不对应
大风险啊
于是Swift中出现了 计算变量这种东西
- 什么叫计算变量 还有什么叫存储变量 ?
什么鬼
我们声明了一种变量就是为了存储数据 但是Swift中有一种特殊的变量 叫做 计算变量 这种变量是 不能存放数据 (你特么又在逗我 )
看官 我真的没逗你 是真的 这种变量主要就是为了 在view里面声明一个只读的变量 去来给页面赋值的 例子
Paste_Image.png这种办法就巧妙的 避开了以前在OC开发iOS时 可能对mvc造成的规则不符的情况
- 这里出现了其他的情况 就是我真的想拥有一个变量 还想在setter方法里面做些别的操作
这里我们出现了先入为主的观念 很多java C++ 和OC开发者 都以为对于的setter就是对应的Set方法 其实不是这样的额
在Swift中访问控制是有访问控制关键字来决定的
如
对于的监听方法就变成了这样
Paste_Image.png在早期 apple 建议开发者 都使用 view 使用kvo去观察model的变化 来给对于的页面赋值 但是也不知道程序员的习惯 还是如何 大家还是我行我素 就在view中拿到model
在Swift中 建议使用计算变量 来给view赋值
- 关于网上对于计算变量的写法
很多人 都模仿 OC中的写法 自己写个带下划线的私有变量 然后提供 set和get方法 我只能说你根本就没有理解Swift 带着陈旧的思想去学习 多此一举嘛
- 关于两个问题
-
我真的想在计算属性里面存值
-
属性观察期的位置 固定了 那以前的kvo怎么办
还记得OC中的面试题吗
category 声明一个property 是什么意思
怎么给category增加成员属性
在oc的category中写了一个property 其实系统帮你做了一个对应的set 和 get方法的声明 具体也不会有私有变量生成 也不会有方法实现 如果你真的要加变量 就要用到kvo的 关联对象 如果你对runtime不熟悉 去简述搜 runtime 很多好文章
在Swift中是这样的
Paste_Image.png关于kvo Swift的初衷就是为了创造几门极度安全化的语言 所以Swift不建议我们再 使用kvo了 因为 在oc中kvo 会产生 一个私有的中间类 (不懂去看runtime ) 在Swift 真的想用kvo 就要用黑魔法了
参看自喵神的tips
“在 Swift 中使用 KVO 有两个显而易见的问题。
首先是 Swift 的 KVO 需要依赖的东西比原来多。在 Objective-C 中我们几乎可以没有限制地对所有满足 KVC 的属性进行监听,而现在我们需要属性有 dynamic 进行修饰。大多数情况下,我们想要观察的类不一定是 dynamic 修饰的 (除非这个类的开发者有意为之,否则一般也不会有人愿意多花功夫在属性前加上 dynamic,因为这毕竟要损失一部分性能),并且有时候我们很可能也无法修改想要观察的类的源码。遇到这样的情况的话,一个可能可行的方案是继承这个类并且将需”“要观察的属性使用 dynamic 进行重写。比如刚才我们的 MyClass 中如果 date 没有 dynamic 的话,我们可能就需要一个新的 MyChildClass 了:”
最后再来个广告 受到 公众号主人邀请 我的文章也会被发布到这个公众号
** 加个欢迎微信扫码关注吧**
Paste_Image.png