类
一、类的介绍和定义
- swift也是一门面向对象开发的语言
2.面向对象的基础是类,类产生了对象
3.在swift中如何定义类呢?
class是类的关键字,用来定义类
class 类名 superClass {
// 定义属性和方法
}
注意:
1. 定义的类,可以没有父类,那么该类是rootClass
2. 通常情况下,定义类时,继承自NSObject(非OC的NSObject)
二、如何定义类的属性
Swift中类的属性有多种 - 存储属性:存储实例的常量和变量
- 计算属性:通过某种方法计算出来的属性
- 类属性:与整个类自身相关的属性
存储属性
存储属性是最简单的属性,它作为类实例的一部分,用于存储常量和变量
可以给存储属性提供一个默认值,也可以在初始化方法中对其进行初始化
/*
* 1. 类的定义
* 2. 创建类的对象
* 3. 给类的属性赋值
1> 直接赋值
2> 通过KVC赋值
* 4. 可以重写setValue(value: AnyObject?, forUndefinedKey key: String),那么字典中没有的字段可以在类中没有对应的属性
* 5. override:重写,如果写的某一个方法是对父类的方法进行重写,那么必须在该方法之前加上override
*/
class Person : NSObject {
var age : Int = 0
// 重写父类的方法
// override:重写,如果写的某一个方法是对父类的方法进行重写,那么必须在该方法之前加上override
override func setValue(value: AnyObject?, forUndefinedKey key: String) {
}
}
let p = Person()
p.age = 20
p.setValuesForKeysWithDictionary(["age": 18, "name": "lmj"])
print(p.age)
类的属性代码示例
class Student: NSObject {
// 定义属性
// 定义存储属性
var age: Int = 0
var name : String? = nil
var mathSource : Double = 0.0
var chineseSource : Double = 0.0
// 定义计算属性:通过别的方式计算到结果的属性,称之为计算属性
var averageSource : Double {
return (mathSource + chineseSource) * 0.5
}
// 定义类属性:类属性是跟整个类相关的属性,而且是通过类名进行访问
static var courseCount : Int = 0
/*
// 定义一个方法,可以返回平均成绩
func getAverageSource() -> Double {
// 在swift开发中,如果使用当前对象的某一个属性,或者调用当前对象的某一个方法时,可以直接使用,不需要加self
return (mathSource + chineseSource) * 0.5
}
*/
}
// 创建对象
let stu = Student()
// 给对象的属性赋值
stu.age = 10
stu.name = "xxs"
stu.mathSource = 120
stu.chineseSource = 59
print(stu.age)
if let name = stu.name {
print(name)
}
类的构造函数
- 构造函数类类似于OC中的初始化方法:Init方法
- 默认情况下创建一个类时,必然会调用一个构造函数
- 即便是没有编写任何构造函数,编译器也会提供一个默认的构造函数
- 如果是继承自NSObject,可以对父类的构造函数进行重写
init(name : String, age : String) {self.name = name, self.age = age}
init(dict: [String : AnyObject]) {dict["name"], dict["age"]} as? as!
init(dict: [String: AnyObject]) {super.init() setValueeForKeysWithDic:dict}
class Person: NSObject {
var name : String?
var age : Int = 0
override init() {
// 在构造函数中,如果没有明确super.init(),那么系统将会帮助调用super.init()
// super.init()
print("----------")
}
// 自定义构造函数
init(name : String, age : Int) {
self.name = name
self.age = age
}
// init(dict : [String: AnyObject]) {
// let tempName = dict["name"]
// // tempName是一个AnyObject?转成String
// // as? 最终转成的类型是一个可选类型
// name = tempName as? String
//
//// let tempAge = dict["age"]
//// age = tempAge as! Int
// // tempName是一个AnyObject?转成String
// // as! 最终转成的类型是一个不可选类型,最好不要这样强制解包
// /*
// let tempAge1 = tempAge as? Int
// if tempAge1 != nil {
// age = tempAge1
// }
// */
//
// if let tempAge = dict["age"] as? Int {
// age = tempAge
// }
//
// }
// 通过kvc给构造函数中的属性赋值
init(dict : [String: AnyObject]) {
super.init()
setValuesForKeysWithDictionary(dict)
}
override func setValue(value: AnyObject?, forUndefinedKey key: String) {}
}
let p = Person()
let p1 = Person(name: "lmj", age: 18)
print(p.name)
print(p1.name)
let p2 = Person(dict: ["name": "we", "age": 15, "height": 120])
print(p2.name)
类里面监听属性的改变使用属性监听器进行监听
// 如何监听某一个类中的属性的改变,可以通过属性监听器来监听属性的改变
class Person: NSObject {
// 属性监听器
var name : String? {
// 监听属性是否改变
// willSet:属性即将改变时进行监听
willSet {
print(name)
print(newValue)
}
// didSet:属性已经改变时进行监听
didSet {
print(name)
print(oldValue)
}
}
}
let p = Person()
p.name = "why"
p.name = "dhs"
class MyCell: UITableViewCell {
var person : Person?
}
闭包
- 闭包和OC中的block非常相似
1.1 OC中的block是匿名的函数
1.2 Swift中的闭包是一个特殊函数
1.3 block和闭包经常用于回调
注意:闭包和block一样,第一次使用时可能不习惯它的语法,可以先按照使用简单的闭包,随着学习的深入,慢慢掌握其灵活的运用方法 - 闭包的基本写法
callBack : (参数列表) -> (返回值类型)
3.闭包的循环引用
1.weak var weakSelf = self weakSelf?
2. [weak self] self? (推荐使用)
3. [unowned self] self
4.尾随闭包
// 闭包的类型:(参数列表) -> (返回值类型)
HttpTool类
func loadData(callBcak : (jsonData : String) -> ()) {
dispatch_async(dispatch_get_global_queue(0, 0)) {
print("发送网络请求:\(NSThread.currentThread())")
dispatch_sync(dispatch_get_main_queue(), {
print("获取到数据,并且进行回调:\(NSThread.currentThread())")
callBcak(jsonData: "jsonData数据")
})
}
}
ViewController类
class ViewController: UIViewController {
// var tools : HttpTool?
var tools: HttpTool = HttpTool()
override func viewDidLoad() {
super.viewDidLoad()
// tools = HttpTool()
}
override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
/* weakSelf?.view
如果前面的可选类型,没有值,后面的代码都不会执行
如果前面的可选类型,有值,系统会自动将weakSelf进行解包,并且使用weakSelf
*/
// 解决循环引用的方式一:
/*
// 0x0 -----> nil
weak var weakSelf = self
tools.loadData { (jsonData) in
// print("在ViewController中拿到数据:\(jsonData)")
weakSelf?.view.backgroundColor = UIColor.redColor()
*/
// 解决循环引用的方式二:(推荐使用该方法)
tools.loadData {[weak self] (jsonData) in
// print("在ViewController中拿到数据:\(jsonData)")
self?.view.backgroundColor = UIColor.redColor()
}
// 解决循环引用的方式三:
tools.loadData {[unowned self] (jsonData) in
// print("在ViewController中拿到数据:\(jsonData)")
self.view.backgroundColor = UIColor.redColor()
}
// 尾随闭包:如果闭包作为方法的最后一个参数,那么闭包可以将()省略掉
// 普通写法:
tools.loadData ({[unowned self] (jsonData) in
// print("在ViewController中拿到数据:\(jsonData)")
self.view.backgroundColor = UIColor.redColor()
})
// 尾随闭包写法一:
tools.loadData() {[unowned self] (jsonData) in
// print("在ViewController中拿到数据:\(jsonData)")
self.view.backgroundColor = UIColor.redColor()
}
// 尾随闭包写法二:
tools.loadData {[unowned self] (jsonData) in
// print("在ViewController中拿到数据:\(jsonData)")
self.view.backgroundColor = UIColor.redColor()
}
}
// deinit相当于OC中的dealloc方法,当对象销毁时会调用该函数
deinit {
print("ViewController-------deinit")
}
}
懒加载
1.swift中也有懒加载的方式
(苹果的设计思想:希望所有的对象在使用时才真正加载到内存中去)
2.和OC中不同的是swift有专门的关键字来实现懒加载
- lazy关键字可以用于定义某一个属性懒加载
懒加载的格式:
lazy var 变量 : 类型 = {创建变量代码}()
// 懒加载的本质是,第一次使用的时候执行闭包,将闭包的返回值赋值给属性
// lazy的作用是只会赋值一次
lazy var array : [String] = {
() -> [String] in
return ["www", "cb", "wds"]
}