Swift3 学习

下`Swift3 学习

在Swift中的可选类型指示里面有值, 且=x 或者 里面没有任何值
有点像OC中的nil指针, 但是不仅局限于类/对象, 可以适用于任何类型
分类可以不用写分类名了? 还是在文件名写好了就不重要了?
self.’do’(闭包)是什么????
枚举也有扩展?

没有了++, –, 只能用a+=1; a-=1; 来代替

reverse & stride

CStyle的for循环没有了, 替代的是区间循环
这样就不能反向循环
需要用区间的函数reverse

1
2
3
for i in (1...10).reverse {
...
}

而且这样区间中的值只能是整数, 而且步长 = 1;
需要调整步长的时候需要在一个函数创造出来的区间才行,

1
2
3
4
for i in stride(from: 0, to: 10, by: 2) {
这个里面的to相当于小于号< 达不到10, 要有<=的效果的话, 就要用throught代替to
...
}

元组可以进行比较

默认情况下先比较第一个的大小, 相等的情况下再比较后面的大小
要修改这种比较规则的话, 可以对比较运算符进行重载, 运算符在Swift3里也是一种函数

1
2
3
4
5
6
func <(t1:(Int, Int), t2:(Int, Int)) -> Bool {
if (t1.1 != t2.1) {
return t1.1 < t2.1
}
return t1.0 < t2.0
}

在函数传参中, 如果参数的数量和类型和元组的一样, 那么在Swift2中可以直接穿一个元组进去, 它会自动解包成对应的参数传递, 但是Swift3中摈弃了, 因为这容易让人困惑, 需要分别提取出元组元素传入

在playground里, 要使用实时预览UIKit相关的话, 要导入import PlaygroundSupport, 并且要把显示的view添加到liveView:

1
PlaygroundPage.current.liveView = viewController.view

button.addTarget(self, action: “click”, for: .touchUpInside) 转变为
button.addTarget(self, action: #selector(click), for: .touchUpInside)

消息selector不在用”消息名”, 而是用类似OC的@selector(), Swift3里用的是#selector();

第一个参数的外部参数名是显示的

不在需要提示blue是color, 直接blue, 取消提示性的名词
UIColor.blueColor() -> UIColor.blue
arr.maxElement() -> arr.max()

//swift2: arr.insert(100, atIndex: 0)
arr.insert(100, at: 0)

// 取消函数名称中无用的词汇
// 包括参数类型和返回值类型

外部参数名默认就是参数名, 不需要的话在外部参数名的地方加上 _ , 相当于占位没有, 或者自己另外设个外参名

参数关键字

Swift3中, 不能在参数中添加关键字 let 和 var了, 要想使用 var 关键的功能的话, 需要在函数中自己设定一个 var 变量. 来操作

inout 关键字

2.x 的时候是在参数名前声明: (inout a: Int) 3.x时: (_ a: inout Int), 使用穿参的时候仍是传地址&a

函数内部在对多个值负值的时候, 可以使用元组一一对应的进行负值

参数默认值

在2.x 中, 有默认值的参数在调用时不用依照定义的顺序, 3.x 中必须要
在3.x 中, 对传入的参数默认强制是 let 常量型, 就不用去设置 var 还是 let, 要是要修改的话, 只能再内部先负值给一个变量值, 再进行操作(可以和形参同名, 这也生推荐的方法)

函数类型

在参数的位置要再加上括号();

函数使用

在类意外的地方使用类中的函数, 之前可以: let f = 函数名; 然后有重载的话就根据参数来确定调用函数
而在 Swift3中, 则是要指明需要的是哪个函数把参数的列表也要写出来

动词函数名
尾缀 -ed 表示过去式, 什么什么过的结果拿来用 -ing 表示名词: 有返回值, 不影响原对象
没有这些尾缀,则为动作,直接作用于原对象

枚举 Enum

枚举命名由开头首字母大写变为首字母小写, 这样再链式调用的时候
enum 相关

map, flatmap, reduce, filter

Swift 中函数式编程的应用
http://swiftcafe.io/2016/03/28/about-map/

Swift 和其他语言一样提供了这些函数, 可以很方便的给数组或者字典做操作, 除reduce 之外, 其他的操作都是返回一个数组. 即使它操作的是字典和 set 的集合类型

闭包

注释

参考文章

用 markdown 语法来给 Swift 进行注释文档

参考
之前的一些第三方完成的项目
生成文档

Swift中的字典类型Dictionary是一个结构体类型

当去处一个可以的value时如果没有这个key对应的值, 会返回一个nil, 因为他value是以optional类型来封装的

在Swift3中根据传入的字符串创建一个控制器

根据字符串获取对应的类加载

1
2
3
4
5
6
7
8
1. 需要获取当前项目的nameSpace(Swift会在底层给你的项目加上一个前缀, 这是在底层的真实使用的类型)
let namespace = Bundle.main.infoDictionary!["CFBundleExecutable"]as!String
2. 拼接类名并转换成ViewController
let vcClass = NSClassFromString(namespace+"."+controller)!as!UIViewController.Type
3. 创建对象
let navigationVC = UINavigationController(rootViewController: vcClass.init())
4. 修改info.plist
在info.plist中的Executable file 字段右键 -> property list Type -> none

这样旧能在获取对应json的数据来创建控制器展现出来, 但是还是需要控制器已经准备好

根据字符串去storyboard获取对应的控制器加载

let vc = UIStoryboard(name: “Main”, bundle: nil).instantiateViewController(withIdentifier: _viewControllerArray[indexPath.row])
显然第二种更简单, 但是需要依赖storyBoard

Swift中的try, do{} catch{}

当一个函数有可能出现错的的时候, 使用throw来声明, 调用这个函数的, 需要使用try来处理
swift的异常处理: 有throw的方法,就要try catch 起来 do{}catch{do中出现错误异常才执行这里的代码}
swift中异常处理的三种方式:
try : 正常处理,必须用到do {} catch {}
try! : 告诉系统一定没有异常,也就是说不用do catch来处理,开发中不建议用.一旦有异常,程序崩溃
try? : 告诉系统可能有异常,也可能没有异常.如果没有异常,系统会自动将结果包装成一个可选类型给你,如果有异常,系统会返回nil.如果使用try?可以不是同do catch进行处理

验证: 在Protocol中能不能设定一个构造方法init 或者 convenient init

测试: 使用Protocol声明init 在JSONAbleType 中, 看看会有什么问题,

  1. 目前可行的是: Protocol声明一个init, 不是convenient init , 类实现时添加required 关键字, 同时实现init(code:) 方法
  2. 方法1的话就替代了init()方法, 不会自己创建这个默认方法了, 需要的话还要自己写一遍
  • 声明一个type property, 需要加上static的keyword, 无论实现的时候你是用class关键字还是static, 也就是说, 声明type property, Protocol中一定要用static, 但在实现时不限定是用class或者是static修饰

对于使用子类化和协议化优化代码

在父类中拥有了很多属性和方法可以实现很多共有的东西, 子类不需要实现时, 使用继承会好点
在需要的种类一样, 而具体的容器或者Presenter之类的需要自己单独化的东西时, 虽然使用继承也可以解决, 但是使用Protocol可以更融洽和谐无侵入, Protocol更像是给Class/struct/enum设计一个骨架, 共同的操作逻辑可以写在extention里, 没有实现的话旧会使用extension里的实现
Protocol中定义的属性不用关心是计算属性还是存储属性, 只能声明这个属性get/set or both.
Protocol中也可以定义init方法, 同样不需要关心这是个convenient还是design, 遵守协议的需要实现这么个方法, 添加关键字require, 可以是design, 也可以是convenient
Protocol可以定制一个init方法,

Protocol Orientation Program 面向协议编程

apple中关于Protocol使用的简单说明和一些Demo

不能在协议扩展里调用来自 Objective-C 的成员
不能使用 where 字句限定 struct 类型
不能定义多个以逗号分隔的 where 从句,类似于 if let 语句
不能在协议扩展内部存储动态变量
该规则同样适用于非泛型扩展
静态变量应该是允许的,但截至 Xcode 7.0 还会打印 “静态存储属性不支持泛型类型” 的错误。
与非泛型扩展不同,不能调用 super 来执行一个协议扩展 @ketzusaka 指出可以通过 (self as MyProtocol).method() 来调用
因为这个原因,协议扩展没有真正意义上的继承概念
不能在多个协议扩展中部署重名的成员方法
Swift 的运行时只会选择最后部署的协议,而忽略其他的
举个例子,如果你有两个协议扩展都实现了相同的方法,那么只有后部署的协议方法的会被实际调用,不能从其他扩展里执行该方法
不能扩展可选的协议方法
可选协议要求 @objc 标签,不能和协议扩展一起使用
不能在同一时刻声明一个协议和他的扩展
如果你真的想要声明实现放在一起,那就使用 extension protocol SomeProtocol {} 吧,因为声明实现都在同一位置,只提供协议实现就好,声明可以省略。

常量的构造

可以使用struct, enum: String 来构造一些常量, 这样更有管理性.
这样的 struct 我们并不打算进行初始化, 所以我们将默认的初始化方法声明为 private. : private init() {}
我们可以使用static 来声明一个静态变量, 这样在使用这些定义的常量的时候旧不用每次都初始化 struct.
在类中使用 static 声明一个属性的话, 效果个 final class 是一样的, 子类将不能继承和重写这些属性
在需要使用的常量和他的变量名一致时, 使用 enum 会更有效率.

使用 Swift , 添加语法糖来使一些东西更好用, 不仅局限于 Swift 给的 Api

使用 extension Protocol 来扩展一些方法函数
associatedType aaa : bbb: 关联类型, 即声明一个类型, 类似 OC 中的 class xxx, 声明这个 Type: 遵守的bbb协议, 这样在这个 extension 中我们就可以使用这个类, 这个 Type 的具体类型, 在遵守了这个协议的 class 或者 struct 中提供, 即使用 typealias xxx = aaa

我们可以在 extension 中定义一个 enum, 来声明是在某个协议下使用的enum.

关于两个遵守了同一协议, 并 提供了相同的 Key 的时候, 这时候的操作是冲突的, 所以应该为 Key 做一个命名空间

extension KeyNamespaceable {
func namespace(_ key: T) -> String where T: RawRepresentable {
return “(Self.self).(key.rawValue)”
}
}
这也是在协议 Protocol 中使用 self, 的方法之一, 使用泛型, 确定类型之后 self 即指代这个类型的对象实例. 如上, Self.self是获取类型
也可以使用 where 关键字来限定使用这个 extension 的条件
参考文章

enum 的高级用法

给图片添加静态的贴纸, 类似微博给照片添加的那种

参考

我即将改写的下拉菜单的原型库

BTNavigationDropdownMenu

开源库

TabBarController

  1. animated-tab-bar ios9.0+, demo介绍没有看到bage的效果
  2. ESTabBarController ios8.0+, demo看到有bage的效果
    以上两个均有动画效果

消息提示控件

  1. Dodo

导航栏

  1. HidingNavigationBar
  2. TLYShyNavBar : 感觉更好点

HUD

  1. 大名鼎鼎的MB
  2. MMProgressHUD 提供了很多show的方式

人脸识别

libfacedetection

上下拉刷新控件

动画

  1. 基于底层的链式语法动画Anima
  2. 基于UIDynamic的仿真物理动画
    3.

类型擦除

是个什么鬼?
好像是可以将在 Swift 中返回值需要限定在某个协议货着类型时, 不对外暴露这个类型或者协议的具体类型而存在的