Swift 快速入门笔记(二)

类的定义和声明
// 类的定义
class Student : NSObject {
    // 存储属性
    // 注意:
    // 1> 如果类型是结构体或者类,通常定义为可选类型
    // 2> 如果是基本属性类型,可以再定义的时候直接初始化为0/0.0
    var name : String?
    var age : Int = 0
    
    var chineseScore : Double = 0.0
    var mathScore : Double = 0.0
    
    //计算属性
    var averageScore : Double {
        // 如果一个计算属性只有getter方法,那么get{}可以省略
        get {
            return ((chineseScore + mathScore) * 0.5)
        }
        
        //可选的setter方法,并且在setter方法中有一个系统的标识符,用于记录外界传入的值
        //newValue
//        set {
//            print(newValue)
//            self.averageScore = newValue
//        }
    }
    
    // 类属性
    static var courseCount : Int = 0
}


let stu : Student = Student()
//设置类属性
Student.courseCount = 2

stu.name = "why"
stu.age = 12

stu.chineseScore = 61
stu.mathScore = 99

监听属性的改变

在OC中我们可以重写set方法来监听属性的改变,Swift中可以通过属性观察者来监听和响应属性值的变化,通常是监听存储属性和类属性的改变.(对于计算属性,我们不需要定义属性观察者,因为我们可以在计算属性的setter中直接观察并响应这种值的变化)

class Person : NSObject {
    //swift 中提供了属性监听器,可以监听属性的改变
    var name : String? {
        // 在willSet方法中,系统提供一个标识符
        // newValue : 用于记录新传入的数据
        
        // 自定义newValue和oldValue的名称
        willSet {
            print(name)
            print(newValue!)
        }
        
        // 在didSet方法中,系统提供一个标识符
        // oldValue : 用户记录之前的值
        didSet {
            print(name)
            print(oldValue)
        }
    }
    var age : Int = 0
}

let p = Person()
p.name = "why"
p.age = 18

// OC监听属性的改变:重写set方法
p.name
类中的构造函数

swift中的构造函数,相当于OC中的init 方法

class Person: NSObject {
    var name : String?
    var age : Int = 0
    
    override init() {
        // 重写之后是否需要调用super.init()
        // 可以不调用,如果没有主动调用,那么系统会默认调用
    }
    
    // 自定义构造函数,初始化时直接传入名字和年龄
    init (name : String,age : Int){
        self.name = name
        self.age = age
    }
    
    // 自定义构造函数,初始化时传入的字典
    // init (dict : Dictionary)
    init(dict : [String : AnyObject]) {
        // 从AnyObject转成String/Int类型,as!
        // 如果Swift转OC类型时,使用 as
        self.name = dict["name"] as? String
        self.age = dict["age"] as! Int
    }
}
类中的方法重载

重载就是在一个类中可以有相同方法名但是方法列表和返回值不同

class MathTool {
    func sum(num1 :Int , num2 : Int) -> Int{
        return num1 + num2
    }
    
    // 方法的重载
    // 1.方法名字相同,但是参数不同,就是方法的重载
    // 2.参数不同:1>参数个数不同 2>参数的类型不同
    func sum(num1 : Double , num2 : Double) -> Double{
        return num1 + num2
    }
}

闭包

闭包和OC中的block非常相似,OC中的block是匿名的函数,Swift中的闭包是一个特殊的函数,block和闭包都经常用于回调
下面通过模拟网络请求来展示如何使用闭包:

//HttpTool.swift
class HttpTool: NSObject {
    
    var callBack : (()->())?
    // 闭包的类型:(参数列表)->()
    // 建议:以后写闭包类型直接:()->()
    func requestData(callBack : @escaping ()->()){
        
        self.callBack = callBack
        
        DispatchQueue.global().async {
            print("网络请求:\(Thread.current)")
            
            DispatchQueue.main.async {
                callBack()
            }
        }
    }
}
//ViewController.swift
class ViewController: UIViewController {

    var httpTool : HttpTool = HttpTool()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    
    override func touchesBegan(_ touches: Set, with event: UIEvent?) {
        
        /*
         给闭包赋值:
         {
         () -> () in
         //代码块
         }
         */
        // 闭包赋值写法一:
        // __weak:当弱指针指向的对象销毁时,指针自动指向nil
        // __unsafe_unretained:当不安全指针指向的对象销毁时,指针依然指向之前的内存地址(野指针)
        httpTool.requestData { [unowned self]()->() in
            self.view.backgroundColor = UIColor.orange
            print("刷新主界面:\(Thread.current)")
        }
        
        // MARK:- 这种写法成为尾随闭包
        
        
        // 闭包赋值写法二:最常用写法
        // 如果该闭包没有参数,也没有返回值,()->() in 可以省略
        // 防止循环引用
        weak var weakSelf : ViewController? = self
        
        httpTool.requestData {
            print("刷新主界面:\(Thread.current)")
            weakSelf!.view.backgroundColor = UIColor.orange
        }
    }

    // Swift中没有dealloc方法
    // 析构函数:相当于OC中的dealloc,也是对象销毁时会调用的函数
    deinit {
        print("ViewController----deinit")
    }
}

懒加载的写法

class ViewController: UIViewController {

    // 1>数据用到时再加载
    // 2>数据只会加载
    lazy var names : [String] = {
        print("加载数据")
        return ["why","yz","lmj","lnj"]
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func touchesBegan(_ touches: Set, with event: UIEvent?) {
        print(names)
    }
    
}

tableView的创建

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 添加一个tableView
        let tableView = UITableView(frame: self.view.bounds, style: UITableViewStyle.grouped)
        tableView.frame = self.view.bounds
        self.view.addSubview(tableView)
        // 设置数据源
        tableView.dataSource = self
        
        // 设置代理
        tableView.delegate = self
    }
}


// 相当于OC中的category
extension ViewController : UITableViewDelegate,UITableViewDataSource{
    // MARK:- tableView数据源方法
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 20;
    }
    // MARK:- tableView代理方法
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let ID = "Cell"
        
        //从缓存池中取出cell
        var cell = tableView.dequeueReusableCell(withIdentifier: ID)
        
        if cell == nil {
            cell = UITableViewCell(style:UITableViewCellStyle.default, reuseIdentifier: ID)
        }
        
        cell?.textLabel?.text = "测试数据\(indexPath.row)"
        return cell!
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("点击了\(indexPath.row)")
    }
}

你可能感兴趣的:(Swift 快速入门笔记(二))