Swift基础知识4

姓名:谢艾芳  学号:16040410073

Swift基础知识4(接上一篇)

转自http://www.jianshu.com/p/02ab8c6c1f9f

〖嵌牛导读〗Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X 和 iOS 应用程序,Swift语言让应用开发更简单、更快、更稳定,确保最终应用有着更好的质量

〖嵌牛鼻子〗Swift基础知识 Swift的编程技巧和方法

〖嵌牛提问〗如何简单学习Swift基本编程语言?

〖嵌牛正文〗

十一、类的使用

1、类的介绍和定义

Swift也是一门面向对象开发的语言,面向对象的基础是类,类产生了对象,class是Swift中的关键字,用于定义类

定义的类,可以没有父类.那么该类是rootClass,通常情况下,定义类时,继承自NSObject(非OC的NSObject)

class 类名 : SuperClass {

    // 定义属性和方法

}

2、定义类的属性

Swift中类的属性有多种:存储属性,存储实例的常量和变量;计算属性,通过某种方式计算出来的属性;类属性,与整个类自身相关的属性

① 存储属性

存储属性是最简单的属性,它作为类实例的一部分,用于存储常量和变量,可以给存储属性提供一个默认值,也可以在初始化方法中对其进行初始化

// 给存储属性赋值

stu.age = 10

stu.name = "xiaoming"

stu.chineseScore = 89.0

stu.mathScore = 98.0

② 计算属性

计算属性并不存储实际的值,而是提供一个getter和一个可选的setter来间接获取和设置其它属性,计算属性一般只提供getter方法,如果只提供getter,而不提供setter,则该计算属性为只读属性,并且可以省略get{}

class Student : NSObject {

    // 存储属性

    var age : Int = 0

    var name : String?

    var chineseScore : Double = 0.0

    var mathScore : Double = 0.0

    // 计算属性

    var averageScore : Double {

        get {

            return (chineseScore + mathScore) / 2

        }

        // 没有意义,因为之后获取值时依然是计算得到的

        // newValue是系统分配的变量名,内部存储着新值

        set {

            self.averageScore = newValue

        }

    }

}

③ 类属性

类属性是与类相关联的,而不是与类的实例相关联,类属性的设置和修改,需要通过类来完成,类属性使用static来修饰

class Student : NSObject {

    // 类属性

    static var corseCount : Int = 0

}

// 设置类属性的值

Student.corseCount = 3

// 取出类属性的值

print(Student.corseCount)

④ 监听属性的改变

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

willSet:在属性值被存储之前设置,此时新属性值作为一个常量参数被传入,该参数名默认为newValue,我们可以自己定义该参数名;didSet:在新属性值被存储后立即调用,与willSet相同,此时传入的是属性的旧值,默认参数名为oldValue;

willSet与didSet只有在属性第一次被设置时才会调用,在初始化时,不会去调用这些监听方法

class Person : NSObject {

    var name : String? {

        // 可以给newValue自定义名称

        willSet (new){ // 属性即将改变,还未改变时会调用的方法

            // 在该方法中有一个默认的系统属性newValue,用于存储新值

            print(name)

            print(new)

        }

        // 可以给oldValue自定义名称

        didSet (old) { // 属性值已经改变了,会调用的方法

            // 在该方法中有一个默认的系统属性oldValue,用于存储旧值

            print(name)

            print(old)

        }

    }

    var age : Int = 0

    var height : Double = 0.0

}

let p : Person = Person()

// 在赋值时,监听该属性的改变

// 在OC中是通过重写set方法

// 在swift中,可以给属性添加监听器

p.name = "xiaoming"

十二、类的构造函数

构造函数类似于OC中的初始化方法init方法,默认情况下载创建一个类时,必然会调用一个构造函数,即便是没有编写任何构造函数,编译器也会提供一个默认的构造函数,如果是继承自NSObject,可以对父类的构造函数进行重写

1、构造函数的基本使用

① 类的属性必须有值,如果不是在定义时初始化值,可以在构造函数中赋值

class Person: NSObject {

    var name : String

    var age : Int

    // 重写了NSObject(父类)的构造方法

    override init() {

        name = ""

        age = 0

    }

}

// 创建一个Person对象

let p = Person()

② 初始化时给属性赋值

我们在创建一个对象时就会给属性赋值,可以自定义构造函数,如果自定义了构造函数,会覆盖init()方法,即不在有默认的构造函数

class Person: NSObject {

    var name : String

    var age : Int

    // 自定义构造函数,会覆盖init()函数

    init(name : String, age : Int) {

        self.name = name

        self.age = age

    }

}

// 创建一个Person对象

let p = Person(name: "xiaoming", age: 18)

③ 字典转模型(初始化时传入字典)

例1

class Person: NSObject {

    var name : String

    var age : Int

    // 自定义构造函数,会覆盖init()函数

    init(dict : [String : NSObject]) {

        name = dict["name"] as! String

        age = dict["age"] as! Int

    }

}

// 创建一个Person对象

let dict = ["name" : "xiaoming", "age" : 18]

let p = Person(dict: dict)

例2

利用KVC字典转模型

class Person: NSObject {

    // 结构体或者类的类型,必须是可选类型,因为不能保证一定会赋值

    var name : String?

    // 基本数据类型不能是可选类型,否则KVC无法转化

    var age : Int = 0

    // 自定义构造函数,会覆盖init()函数

    init(dict : [String : NSObject]) {

        // 必须先初始化对象

        super.init()

        // 调用对象的KVC方法字典转模型

        setValuesForKeysWithDictionary(dict)

    }

}

// 创建一个Person对象

let dict = ["name" : "xiaoming", "age" : 18]

let p = Person(dict: dict)

十三、闭包

Swift闭包和OC中的block非常相似,OC中的block是匿名的函数,Swift中的闭包是一个特殊的函数,block和闭包都经常用于回调

1、OC中Block的使用

首先介绍一下OC中Block写法

① 第一种Block方式

@property (nonatomic, copy) void(^callBack)(NSString *name);

callBack 是block对象

回调方法

if(_callBack){

_callBack(name)

}

② 第二种Block方式

typedef void(^CallBack)(NSString *str);

@property (nonatomic, copy) CallBack callback;

callback是block对象

回调方法

if(_callBack){

_callBack(name)

}

③ 第三种Block方式

- (void)setUpWith:(void(^)(NSString *str))callback;

callback是block对象

回调方法

if(_callBack){

_callBack(name)

}

总结

Block的写法:

    类型:

    返回值类型(^block的名称)(block的参数)

    值:

    ^(参数列表) {

        // 执行的代码

    };

2、Swift中闭包的使用

① 第一种闭包方式

var callBack : (()->())?

② 第二种闭包方式

func loadRequest(callBack : ()->()){

                callBack()

    }

总结

闭包的写法:

  callBack: (形参列表) -> (返回值类型)

    类型:(形参列表) -> (返回值类型)

    值:

    {

        (形参) -> 返回值类型 in

        // 执行代码

    }

闭包的简写,如果闭包没有参数,没有返回值,in和in之前的内容可以省略

尾随闭包写法

① 如果闭包是函数的最后一个参数,则可以将闭包写在()后面

    httpTool.loadRequest() {

        print("回到主线程", NSThread.currentThread());

    }

② 如果函数只有一个参数,并且这个参数是闭包,那么()可以不写

    // 开发中建议该写法

    httpTool.loadRequest {

        print("回到主线程", NSThread.currentThread());

    }

3、闭包的循环引用

如果在HttpTool中有对闭包进行强引用,则会形成循环引用,在Swift中检测一个对象是否销毁,可以实现对象的deinit函数

// 析构函数(相当于OC中dealloc方法)

    deinit {

        print("ViewController----deinit")

    }

4、swift中解决循环引用的方式

① 使用weak,对当前控制器使用弱引用

但是因为self可能有值也可能没有值,因此weakSelf是一个可选类型,在真正使用时可以对其强制解包(该处强制解包没有问题,因为控制器一定存在,否则无法调用所在函数)

解决一

weak var weakSelf = self

    httpTool.loadData {

        print("加载数据完成,更新界面:", NSThread.currentThread())

        weakSelf!.view.backgroundColor = UIColor.redColor()

    }

② 可以写在闭包中,并且在闭包中用到的self都是弱引用

解决二

httpTool.loadData {[weak self] () -> () in

        print("加载数据完成,更新界面:", NSThread.currentThread())

        self!.view.backgroundColor = UIColor.redColor()

    }

③ 使用关键字unowned

unowned 更像OC中的 unsafe_unretained,unowned 表示即使它原来引用的对象被释放了,仍然会保持对被已经释放了的对象的一个 "无效的" 引用,它不能是 Optional 值,也不会被指向 nil

解决三

httpTool.loadData {[unowned self] () -> () in

        print("加载数据完成,更新界面:", NSThread.currentThread())

        self.view.backgroundColor = UIColor.redColor()

    }

十四、懒加载

swift中也有懒加载的方式,希望所有的对象在使用时才真正加载到内存中,和OC不同的是swift有专门的关键字来实现懒加载,lazy关键字可以用于定义某一个属性懒加载

1、懒加载普通方式

lazy var 变量:类型 = 系统类()

lazy var button:UIButton = UIButton()

2、懒加载升级方式

lazy var array : [String] = {

        () -> [String] in

        return ["xiaoming", "xl", "lisi"]

    }()

你可能感兴趣的:(Swift基础知识4)