无意间看到自己以前学习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
每次调用时都会被执行
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: Int
init(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) {}