类
类的定义和声明
// 类的定义
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)")
}
}