**** 类的相关基础语法
1.类的属性:存储属性,计算属性,类属性
//类
class student {
//类的存储属性
var name : String = ""
var age :Int = 0
var mathScore : Double = 0.0
var chineseScore : Double = 0.0
//类的计算属性
var averageScore : Double {
return (self.mathScore + self.chineseScore)/2
}
//类属性
static var courseCount : Int = 0
//获取平均分儿的函数
/*
func getAverageScore () -> Double {
return (self.mathScore + self.chineseScore)/2
}
*/
}
//存储属性访问
let stu = student()
stu.name = "小明"
//计算属性访问
let averageS = stu.averageScore
//类属性访问,使用类名访问
student.courseCount
2.类的属性监听器(监听属性的改变)
class students {
//属性监听器
var name : String = "" {
//属性即将发生改变
willSet {
print("name 即将改变")
}
//属性已经发生改变
didSet {
//得到改变后的name
print(name)
}
}
}
3.类的重写构造函数,写model 数据模型时候的写法
class person : NSObject {
var name : String = ""
var age : Int = 0
init(dic:[String : Any]) {
super.init()
//用kvc 的方式给 属性赋值
setValuesForKeys(dic)
if let name = dic["name"] as? String {
self.name = name
}
}
//一些多余的属性不能一一对应赋值的话,就写上这个语句儿。
override func setValue(_ value: Any?, forUndefinedKey key: String) {}
}
4.析构函数,相当于oc 中的dealloc
class persons {
var name : String = ""
var age : Int = 0
//析构函数,相当于oc 中的dealloc 函数
deinit {
print("这个persons 类对象即将销毁")
}
}
可选链就是一连串的可选类型,取值的时候用" ?. "来取,赋值也用" ?. "来赋值。没什么好说的,但是,swift 编程里到处可见可选链
//顾名思义,可选类型的一串儿链条
class Person {
//多一嘴,平常的编码规范,一般对象属性用可选类型,值属性直接赋个初始值
var dog : Dog?
var height : Double = 0.60;
}
class Dog {
var toy : Toy?
}
class Toy {
var name : String = ""
}
let p = Person()
//可选链取值
let t = p.dog?.toy?.name
//可选链赋值
p.dog?.toy?.name = "飞碟"
****协议,代理的基本写法
//为什么要加class 加class之后就只能被类遵守了,不能被结构体了,枚举类遵守了
@objc protocol motionProtocol : class {
func basketballMotion ()
//可选方法前面要加 optional ,但是 optional 是oc 的方法,所以要在前面加 @objc
@objc optional func playFootball ()
}
//直接冒号后跟协议遵守协议
class person : motionProtocol {
func basketballMotion() {
print("打篮球")
}
func playFootball() {
print("踢足球")
}
}
//有继承的类,加个逗号分隔开,后跟协议遵守
class per :NSObject , motionProtocol {
func basketballMotion() {
print("打篮球")
}
func playFootball() {
print("踢足球")
}
}
class student {
//为什么加weak 防止循环引用,但是如果protocol 后面没跟:class 加weak 属性就会报错
//因为weak 不能修饰枚举,结构体,只能修饰类
weak var delegate : motionProtocol?
func goToPlayGround (){
delegate?.basketballMotion()
}
}
****闭包,(闭包的书写注意事项比较多,请认真看代码中的注释)
代码是模拟封装网络请求,返回数据要用闭包形式返回,主要注意书写规范
import UIKit
//swift 创建的类如果用不到NSObject 的特性,可以不继承自NSObject ,这样可以使类更轻量级
class httpTool{
//声明一个闭包属性的写法
var finishCallBack :( (_ jsonData:String) -> () )?
//闭包的固定写法: (_参数列表)-> (返回值类型)
//闭包里传递的参数前面必须加下划线
// escaping 逃逸的,这个闭包再别的地方被使用,就必须加上 @escaping 关键字
func requestData (finishedCallBack:@escaping (_ jsonData:String)->()) {
//模拟异步请求网络数据
DispatchQueue.global().async {
print("发送异步网络请求\(Thread.current)")
//回到主线程刷新UI
DispatchQueue.main.sync {
/*>1.如果不让httpTool 强拥有 闭包,就不会形成循环引用,如果拥有了,就需要使用的时候,
闭包对 controll 控制器弱引用
>2.什么时候写属性的时候需要强制写上self.
(1). 当属性的名字,跟变量的名字有冲突的时候
(2).在闭包里
*/
self.finishCallBack = finishedCallBack
print("回到主线程\(Thread.current)")
finishedCallBack("json数据")
}
}
}
}
下面是controll 里的调用
import UIKit
import Foundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
/// override 关键字,在重写父类方法的时候方法前面必须加 override
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let httpRequest = httpTool();
//解决循环引用的方案
// 方案一
/*
weak var weakSelf : ViewController? = self
httpRequest.requestData(finishedCallBack: { (jsonData) in
weakSelf?.view.backgroundColor = UIColor.red
print("jsonData\(jsonData)")
})
*/
//方案二: (之后写代码常用方案)
//[weak self] 也可以写成 [unowned self] 但是 unowned 关键字容易产生野指针,不建议这么写
httpRequest.requestData(finishedCallBack: {[weak self] (jsonData) in
//所有weak 修饰的对象都是可选类型的
self?.view.backgroundColor = UIColor.red
})
//尾随闭包 (了解)
//当闭包是函数的最后一个参数的时候可以写成尾随闭包
//
// httpRequest.requestData() {[weak self] (jsonData) in
// //所有weak 修饰的对象都是可选类型的
// self?.view.backgroundColor = UIColor.red
// }
//
}
}
**** 懒加载写法
//MARK: -- 懒加载
//前面直接加lazy 关键字的写法
lazy var name : [String] = ["李梅","小明","小东"]
//通过闭包的方式懒加载,开发中常用到的写法
lazy var score : [String] = {
let score = ["12","14","16"]
return score
}()