iOS OC/Swift 知识点杂烩(一)

分类(category)、类的扩展(extension)、协议(protocol)特点及应用场景

分类特点

  • 分类是用于给原有类添加方法的,因为分类的结构体指针中,没有属性列表,只有方法列表。
  • 如果分类中有和原有类同名的方法, 会优先调用分类中的方法, 就是说会忽略原有类的方法,同名方法调用的优先级为 分类 > 本类 > 父类
  • 如果多个分类中都有和原有类中同名的方法, 那么调用该方法的时候执行谁由编译器决定;编译器会执行最后一个参与编译的分类中的方法。
  • 分类可以有多个,也就是一个类可以有多个分类
  • 运行时决议,同名分类方法生效取决于编译顺序
  • 名字相同的分类会引起编译报错

分类的用途

  • 可以为系统的类添加我们想要的方法。
  • 多人合作时,由于功能的不同可能需要多个不同的方法,我们只需创建一个类,每个人分别用类别的方法去为类添加自己需要的方法,这样节省开发时间,出错率也很小。

类的扩展特点

  • 声明私有属性
  • 声明私有方法
  • 声明私有成员变量
  • 编译时决议
  • 只以声明存在,寄生于宿主类.m中
  • 不能为系统类添加扩展

分类、扩展区别

  • 分类中原则上只能增加方法(能添加属性的的原因只是通过runtime解决无setter/getter的问题而已);
  • 类扩展不仅可以增加方法,还可以增加实例变量(或者属性),只是该实例变量默认是@private类型的(
    用范围只能在自身类,而不是子类或其他地方);
  • 类扩展中声明的方法没被实现,编译器会报警,但是类别中的方法没被实现编译器是不会有任何警告的。这是因为类扩展是在编译阶段被添加到类中,而类别是在运行时添加到类中。
  • 类扩展不能像类别那样拥有独立的实现部分(@implementation部分),也就是说,类扩展所声明的方法必须依托对应类的实现部分来实现。
  • 定义在 .m 文件中的类扩展方法为私有的,定义在 .h 文件(头文件)中的类扩展方法为公有的。类扩展是在 .m 文件中声明私有方法的非常好的方式。

OC协议以及协议的使用

  • 因为继承的耦合性强,并且oc是单继承的,所以协议就应用而生,协议是一系列标准的方法列表,可以被任何类实现。
  • 协议中不能声明成员变量,只要一个类遵守了这个协议,也相当于拥有了该协议中所有方法的声明。
  • 根据继承的规则,只要父类遵守了该协议,那么它的子类也就都遵守该协议,并且一类中可以遵守多个协议,最常用的就是UITableView啦,遵守了UITableViewDelegate, UITableViewDataSource两个协议
  • 协议中有两种情况,一种是必须要实现的required,一种是可选择实现optional。
  • 一个协议可以遵守其他的多个协议,相当于他用了其他协议方法的声明。
  • 可以定义对象的时候,限制这个类去遵守这个协议。

Swift协议及特性

swift与OC协议共同点

  • 本质都是抽取不同类的共同方法和属性(声明),供遵循协议的类或对象使用。
  • 都可以通过定义协议实例deleagate,来实现委托代理模式。

swift与OC协议区别(核心)

OC协议

  • OC协议更单纯的受限于委托代理的含义,多用于跨类的传值和回调通知。

swift协议

  • Swift可以通过协议 extension 扩展,缺省实现协议的方法(OC不行)。
  • 定义属性方法
  • Swift是面向协议编程,其思想是通过抽取不同类中的相同方法和属性,实现模块化减少耦合。
  • Swift的协议不需要单独声明协议对象(**id delegate **)和指定代理( delegate = self ),只需要遵循协议的类实现声明,或使用协议的缺省实现。

为何说Swift是面向协议协议编程?

  • 传统的协议(比如Objective-C的protocol)只能定义接口,不能复用实现,遵守同一个协议的不同的类,只能分别实现协议接口,使用场景受限了很多。
  • Swift只是多了一个协议扩展的特性,但却带来了编程范式的进化。

面向协议编程(POP)与面向对象编程(OOP)

面向协议编程(简称 POP)定义

面向协议编程是在面向对象编程基础上演变而来,将程序设计过程中遇到的数据类型的抽取(抽象)由使用基类进行抽取改为使用协议(Java语言中的接口)进行抽取
区别

面向对象编程(简称OOP)定义

面向对象顾名思义就是把现实中的事务都抽象成为程序设计中的“对象”,其基本思想是一切皆对象,是一种“自下而上”的设计语言,先设计组件,再完成拼装。OOP的三大特性:封装、继承、多态

特点区分

  • 面向对象编程使用类和继承的手段,数据类型是引用类型;
  • 面向协议编程使用的是遵守协议的手段,数据类型是值类型(Swift中的结构体或枚举)。

总结

Swift是一门支持多编程范式的语言,既支持面向对象编程,也支持面向协议编程,同时还支持函数式编程。在项目开发过程中,控制器和视图部分由于使用系统框架,应更多采用面向对象编程的方式;而模型或业务逻辑等自定义类型部分,则应优先考虑面向协议编程。


if let 与 guard let 用法

if let 用法

  • 普通if与if let的比较,如果常量是可选项(Optional),if判断后仍然需要解包(!)
let name: String? = "mike"
let age: Int? = 10
 
if name != nil && age != nil {
    print(name! + String(age!))     // 输出: mike 10
}

  • 如果常量是可选项(Optional),if let判断后不需要解包(!),{ }内一定有值
let name: String? = "mike"
let age: Int? = 10
 
// if let 连用,判断对象的值是否为'nil'
if let nameNew = name,
    let ageNew = age {
    // 进入分支后,nameNew 和 ageNew 一定有值
    print(nameNew + String(ageNew)) // 输出: mike 10
}

  • if var的用法,和if let的区别就是可以在{}内修改变量的值
let name: String? = "mike"
let age: Int? = 10
 
if var nameNew = name,
    let ageNew = age {
    // 'var'修饰,可以修改'nameNew'的值,'let'修改的不可以修改
    nameNew = "nero"
    print(nameNew + String(ageNew))     // 输出: nero 10
}

guard let用法

  • guard let和if let刚好相反,guard let守护一定有值。如果没有,直接返回。
  • 通常判断是否有值之后,会做具体的逻辑实现,通常代码多
  • 如果用 if let凭空多了一层分支,guard let是降低分支层次的办法
  • guard let语法是 Swift 2.0 推出的
let name: String? = "mike"
let age: Int? = 10
 
guard let nameNew = name,
    let ageNew = age else {
        print("姓名 或 年龄 为nil")
        return
}
// 代码执行至此, nameNew 和 ageNew 一定有值
print(nameNew + String(ageNew))     // 输出: mike 10

你可能感兴趣的:(iOS OC/Swift 知识点杂烩(一))