swift学习(面向对象)

无意间看到自己以前学习swift的笔记,从近两年苹果的发布会,可以看出苹果推动swift的决心,OC更换为swift也是未来发展的趋势,想起当初自己钻研学习swift的痛苦的情景,现在把它们整理出来并与现在最新的swift结合以供初学者使用,让初学者少走弯路。有时间会陆续整理后面知识的学习笔记。 属性的定义和赋值 存储型属性的初始赋值

  • 在 classs 的大括中像定义一个变量或常量一样,定义一个属性
  • 定义时可以设一个默认值
  • 如果没有设默认值,需要在构造器中为属性设初值
  • 构造完成的对象可以通过点语法修改属性的值
class Person { var name: String var age: Int var kindname: String? = "旺财"init(name: String, age: Int) { self.name = name self.age = age } }

通过闭包和函数来设置属性的默认值
  • 闭包结尾的大括号后面接了一对空的小括号,表示立刻执行该闭包
  • 需要在闭包中 return 一个值,赋给该变量
class Person { var weight:Float = { return 165 }() } let xiaoMing = Person() xiaoMing.weight = 175 print("xiaoMing的身高是\(xiaoMing.weight)")

如果你使用闭包来初始化属性的值,请记住在闭包执行时,实例的其它部分都还没有初始化。
这意味着你不能够在闭包里访问其它的属性,就算这个属性有默认值也不允许。
同样,你也不能使用隐式的self属性,或者调用其它的实例方法
存储属性与计算属性
  • 存储属性需要分配内存空间存储属性的值
  • 计算属性不存储值,更像是调用一个函数,返回函数的结果
class Person { var name: String var age: Int var kindname: String { return "亲爱的\(name)" }init(name: String, age: Int) { self.name = name self.age = age } }struct Point { var x = 0.0, y = 0.0 } struct Size { var width = 0.0, height = 0.0 } struct Rect { var origin = Point() var size = Size() var center: Point { get { let centerX = origin.x + (size.width / 2) let centerY = origin.y + (size.height / 2) return Point(x: centerX, y: centerY) } set(newCenter) { origin.x = newCenter.x - (size.width / 2) origin.y = newCenter.y - (size.height / 2) } } } var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height: 10.0)) let initialSquareCenter = square.center square.center = Point(x: 15.0, y: 15.0)

可选属性 对于存储属性:
  • 可选的 var 属性,如果没有赋初值,它有一个默认的初始值 nil
  • 可选的 let 属性,如果没有赋初值,默认值为空。需要在构造函数里赋值
class Person { let girlFriend: Int? var boyFriedn: Int? var name: String var age: Int var kindname: String { return "亲爱的\(name)" }init(name: String, age: Int, girlFriend) { girlFriend = Person() self.name = name self.age = age } }

属性观察器
  • 可以用属性观察器观察属性的变化
  • willSet 有一个默认的参数 newValue
  • didSet 有一个默认的参数 oldValue
  • 存储型属性设置默认值或者在构造器中为其赋值时, 不会触发属性观察器
var weight: Float { willSet { if weight < 90 { print("吃吃吃:\(newValue)") } }didSet { if weight > 180 { print("该减肥了:\(oldValue)") } } }

懒加载 特点
  • 第一次被调用的时候初始化
  • 必须使用 var, 因为属性的初始值可能在实例构造完成之后才会得到, 而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性
  • 使用lazy来标示一个延迟存储属性
class Person {var weight: Int = 100//懒加载 lazy var health: String = { return weight > 100 ? "不健康" : "健康" }() }

懒加载、用闭包给存储属性赋默认值、计算属性区别
  • 懒加载
    • 值会存储
    • 需要加lazy
    • 可以使用 self
    • 闭包必须执行
    • 只执行一次
  • 用闭包为属性赋默认值
    • 值会存储
    • 不可以使用 self
    • 设默认值只执行一次
    • 只执行一次
  • 计算型属性
  • 不存储值,只返回结果
  • 不可以使用 self
  • 【swift学习(面向对象)】每次调用时都会被执行
class Person {var weight: Int = 100// 为属性赋默认值 var height:Float = { return 165 }()//计算属性 var morningHeight: Float { return height + 10 }//懒加载 lazy var health: String = { return weight > 100 ? "不健康" : "健康" }() }

方法 方法的定义和调用
class Person {var name:String var age: Intinit(name: String age:Int) { self.name = name self.age = age }//实例方法 func earnMoney(earnedMoney: Double){ money += earnedMoney } }let xiaoming = Person(name: "XiaoMing", age: 15) xiaoming.earnMoney()

实例方法与类方法
  • 实例方法是被类型的某个实例调用的方法
  • 类方法是给类本身调用的方法
  • 一个方法实现类的某个特定功能
class Person { static var country = "china" //类属性//类方法 static func changeCounry(newCountry: String){ country = newCountry }//类方法 override static func changeCounry(newCountry: String){ country = newCountry }//实例方法 func earnMoney(earnedMoney: Double){ money += earnedMoney } }

类的构造 构造器 类的构造过程,就是在创建对象的时候,为对象分配内存空间,确保对象的所有存储属性都有默认值的过程。
构造器,就是为所有没有默认值的属性设置默认值的函数
  • 默认构造器
    • 如果所有属性都有默认值,swift会为类提供一个默认构造器,其调用方式为 ?SomeClass()
class Person () { var postion: String = "earth" var leg: Int = 2 var arm: Int = 2 var hourse: String? } //所有属性都有默认值,swift会提供一个默认的构造器 let person = Person()

  • 指定构造器
  • 自已定义的构造器
  • 可以初始化属性
  • 必须调用其直接父类的指定构造器
class Person () { var postion: String = "earth" var leg: Int = 2 var arm: Int = 2 var hourse: String? var name: String var age: Int init(name:String, age: String) { self.name = name self.age = age } } //所有属性都有默认值,swift会提供一个默认的构造器

  • 便利构造器
  • 简化类的构造过程
  • 本身不负责属性的创建和初始化工作
  • 调用指定构造器为属性指定初始值
//1. 必须使用convenience修饰 //2. 必须先调用指定构造器//相当于oc中的category extension UILabel { convenience init (title: String, fontSize: CGFloat = 13, textColor: UIColor = UIColor.darkGray, alignMent: NSTextAlignment = .left, numOfLines: Int = 0) { //调用指定构造器,保存所有的存储属性被正确初始化 self.init() //此时对象已创建 self.text = title self.font = UIFont.systemFont(ofSize: fontSize) self.textColor = textColor self.textAlignment = alignMent self.numberOfLines = numOfLines } }/ /便利构造器:主要用 简化类的构造过程的 //便利构造器的用法二: //判断构造条件是否成立,如果成立,就调用指定构造器,完成构造过程 //如果不成立,就返回nil //此时返回的是一个可选值 convenience init?(name: String, age: Int) { if age > 249 { return nil } self.init(name: name) }

然后直接在需要的时候使用
//便利构造器的写法let label = UILabel(title: "hello, world", fontSize: 13, textColor: UIColor.red, alignMent: .left, numOfLines: 0)let label2 = UILabel(title: "hello, world")

kvc 构造器
  • 是用 kvc 来为类属性赋值的方式,完成类的构造过程的构造函数。
  • KVC 是 OC 特有的,KVC 本质上是在运行时,动态向对象发送 setValue:ForKey: 方法,为对象的属性设置数值
  • 在使用 KVC 方法之前,需要确保对象已经初始化
  • 基本数据类型,与 kvc 不兼容,在运行时找不到 key 值,需定义成必选,并赋初值才能完成构造
    class Person: NSObject {
    var name: String?
    var age: Int = 0
    //super.init() 在构造函数中, 如果没有手动添加, 则会自动添加在构造函数的最后面
init(dict: [String: Any]) { super.init() //对象此时已创建 setValuesForKeys(dict) }override func setValue(_ value: Any?, forUndefinedKey key: String) {}

    推荐阅读