补充一下Swift的相关知识。

属性观察器 willSet , didSet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import Cocoa

struct Person {
var name: String = "unknown"{
willSet(new_Value){ //不设置变量时会有一个默认的变量为 newValue
print("new value is \(new_Value)")
}didSet(old_Value){ //不设置变量时会有一个默认的变量为 oldValue
print("old value is \(old_Value)")
}
}
}

var a = Person(name: "Bob")

a.name = "XiaoMing"

/*
new value is XiaoMing
old value is Bob
*/

下标语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
struct Goods {
private var goodsList: [String] = ["手机","电脑","饭盒","盒饭"]

subscript(goodNum: Int) -> String {
set {
goodsList.insert(newValue, at: goodNum)
} get {
return goodsList[goodNum]
}
}
}

var shop = Goods()
shop[1] = "水杯"
print(shop[1])

/*
水杯
*/


//其他例子
struct Book {
private var bookAuthor = [String]()

subscript(rank: Int) -> String {
set(authorName){
bookAuthor.insert(authorName, at: rank)
} get {
return bookAuthor[rank]
}
}
}

var swiftTest = Book()
swiftTest[0] = "Hello world"
swiftTest[1] = "People"
print(swiftTest[0])

/*
Hello world
*/

类与结构体区别

类是传引用,结构体是传值。常量或变量的类的实例不影响类的修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

class ClassStudent {
var name: String = "unknown"
var age: Int = 0
var score: Double = 0.0

init(name: String, age: Int, score: Double) {
self.name = name
self.age = age
self.score = score
}
}

struct StructStudent {
var name: String = "unknown"
var age: Int = 0
var score: Double = 0.0

init(name: String, age: Int, score: Double) {
self.name = name
self.age = age
self.score = score
}
}

var a = ClassStudent(name: "小A", age: 10, score: 12)
var b = StructStudent(name: "小B", age: 49, score: 60)

var c = a
print(a.name)
print(c.name)
c.name = "小C"
print(a.name)
print(c.name)

/*
小A
小A
小C
小C
*/

var d = b
print(b.name)
print(d.name)
d.name = "小D"
print(b.name)
print(d.name)

/*
小B
小B
小B
小D
*/

Any类型和AnyObject类型

1
2
3
4
5
6
7
8
9
10
11
12
13
class A {

}
struct B {

}

var c: Any = A() //Any可以表达任何一个类型
var d: Any = "hahaha"

var e: AnyObject = A() //AnyObject只能表达类
//var f: AnyObject = B() //会报错

类的继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import Cocoa

class A {
private var name: String = "unknown"
func getName() -> String {
return name
}
func setName(newName: String) {
self.name = newName
}
}

class B: A {
func play(times: Int) {
print(times)
}
}

var c = A()
print(c.getName())

var d = B()
print(d.getName())
d.play(times: 3)

/*
unknown
unknown
3
*/

向下类型转换as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import Cocoa

class A {
private var name: String = "unknown"
func getName() -> String {
return name
}
func setName(newName: String) {
self.name = newName
}
}

class B: A {
func play(times: Int) {
print(times)
}
}

//父类类型的引用指向子类类型的对象
var a: A = B()

//判断是否属于该类型的is语法
var b: AnyObject = B()
print(b is B)

/*
true
*/

//向下类型转换
var c = b as? B //转换为可选类型
var d = b as![]B //强制转换

重写方法override

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Person {
var name = "unknown"
var age = 0

func getName() -> String {
return self.name
}

init(name: String, age: Int) {
self.name = name
self.age = age
}
}
class Student: Person {
override var name: String { //重写变量
set{
super.name += " - student"
}get{
return super.name
}
}
override func getName() -> String {
return super.name + " - studentfunc"
}

override init(name: String, age: Int) {
super.init(name: name, age: age)
self.name = name
}
}

var a = Person(name: "小A", age: 12)
print(a.name)

var b = Student(name: "小B", age: 14)
print(b.name)

print(b.getName())

final禁止继承和重写方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//禁止继承
final class Person {
var name = "unknown"
var age = 0

func getName() -> String {
return self.name
}

init(name: String, age: Int) {
self.name = name
self.age = age
}
}
//class Student: Person { //无法继承
// override var name: String { //重写变量
// set{
// super.name += " - student"
// }get{
// return super.name
// }
// }
// override func getName() -> String {
// return super.name + " - studentfunc"
// }
//
// override init(name: String, age: Int) {
// super.init(name: name, age: age)
// self.name = name
// }
//}
//
//var a = Person(name: "小A", age: 12)
//print(a.name)
//
//var b = Student(name: "小B", age: 14)
//print(b.name)
//
//print(b.getName())

final禁止重写方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Person {
var name = "unknown"
var age = 0

final func getName() -> String {
return self.name
}

init(name: String, age: Int) {
self.name = name
self.age = age
}
}
class Student: Person {
override var name: String { //重写变量
set{
super.name += " - student"
}get{
return super.name
}
}
// override func getName() -> String {
// return super.name + " - studentfunc"
// }

override init(name: String, age: Int) {
super.init(name: name, age: age)
self.name = name
}
}

var a = Person(name: "小A", age: 12)
print(a.name)

var b = Student(name: "小B", age: 14)
print(b.name)

多态的调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class A {
var name: String = "unknown"
func getName() -> String {
return self.name
}
init(name: String) {
self.name = name
}
}
class B: A {
override func getName() -> String {
return super.name + " - B"
}

func play(){
print("world")
}
}

var a: A = B(name: "hello")
print(a.getName()) //多态可以调用子类重写的方法

/*
hello - B
*/

//a.play() //多态只能调用父类方法

类的扩展extension

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import Cocoa

class A {

}
extension A {
var name: String {return "hello,world"}
func make() {
print("this is A")
}
}

var a = A()
a.make()
print(a.name)

/*
this is A
hello,world
*/

//例子
import Cocoa

extension String {
func pcount() -> String {
return "长度 = " + String(self.count)
}
}

var a = "hello"
print(a.pcount())

/*
长度 = 5
*/

泛型

可以用一个代码来代替各种类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func todoit<T>(param: T) -> T {
return param
}

print(todoit(param: "hello"))
print(todoit(param: 123))
print(todoit(param: [1,2,3]))
print(todoit(param: 1.1))

/*
hello
123
[1, 2, 3]
1.1
*/

协议protocol

类必须要遵守协议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import Cocoa

class A {

}

protocol Protocol1 {
var a1: String { get set }
func b1() -> String
}

protocol Protocol2 {
var a2: String { get }
func b2() -> String
}

class B: A, Protocol1, Protocol2 {
var a1: String
var a2: String

func b1() -> String {
return a1
}

func b2() -> String {
return "hello world"
}

init(a: String) {
self.a1 = a
self.a2 = a
}
}

var a = B(a: "swift")

print(a.a1)
print(a.a2)
print(a.b1())
print(a.b2())

类型判断处理if A is B

在多个子类做判断时利用is语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class A {

}
class B: A {
var name: String = "unknown"
func printName() {
print(self.name + " - B")
}
init(name: String) {
self.name = name
}
}
class C: A {
var name: String = "unknown"
func printName() {
print(self.name + " - C")
}
init(name: String) {
self.name = name
}
}

func calam(num: Int) -> A {
if num > 10 {
return B(name: "小B")
}else{
return C(name: "小C")
}
}

var n = calam(num: 20)
if (n is B) { //写法1
var p = n as![]B
p.printName()
}else if (n is C) {
var p = n as![]C
p.printName()
}

if let t = n as? B { //写法2
t.printName()
}else if let t = n as? C {
t.printName()
}

判断两个对象是否相等===

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A{

}
var a = A()
var b = A()

print(a === b)

/*
false
*/

print(a !== b)

/*
true
*/

延迟属性lazy

延迟属性可以只在用到属性时进行实例化,可以优化性能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import Cocoa

class A {
init() {
print("A is run")
}
func play() {
print("A is play")
}
}

class B {
lazy var a: A = A()

init() {
print("B is run")
}
}

var a = B()

/*
B is run
*/

a.a

/*
B is run
A is run
*/

a.a.play()

/*
B is run
A is run
A is play
*/

可失败的初始化器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import Cocoa

class A {
var name: String

init? (name: String) {
if name == "world" {
return nil
}
self.name = name
}
}

var t1: A? = A(name: "hello")
var t2: A? = A(name: "world")

//测试t1
if let a = t1 {
print(a.name)
}else{
print("初始化失败")
}

//测试t2
if let a = t2 {
print(a.name)
}else{
print("初始化失败")
}

/*
hello
初始化失败
*/

参考资料

Swift编程基础