CSJ记录点滴

不要用任何借口去阻止你学习


  • 首页

  • 标签

  • 分类

  • 归档

  • 关于

《浅入浅出Swift》NestedTypes 嵌套类型

发表于 2014-08-07 | 分类于 Swift , NestedTypes , 嵌套类型 | 阅读次数:
字数统计: 287 字 | 阅读时长 ≈ 2 分钟

NestedTypes

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

struct BlackjackCard{
//nested Suit enumeration 嵌套适合的枚举
enum Suit: Character{//性格品质
case Spades = "♠", Hearts = "♡", Diamonds = "♢", Clubs = "♣"
}

enum Rank: Int {
case Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King, Ace

struct Values {
let first: Int, second: Int?
}
var values : Values{
switch self{
case .Ace:
return Values(first: 1, second: 11)
case .Jack, .Queen, .King:
return Values(first: 10, second: nil)
default:
//使用toRaw 和fromRaw 两个函数,实现原始值和枚举值之间进行切换
//定义原始枚举类型是Int型,只需要给第一个定义枚举赋值,后续会顺序分配;
//你也可以使用浮点型和String类型作为枚举的原始类型
return Values(first: self.toRaw(), second: nil)
}
}
}
阅读全文 »

《浅入浅出Swift》TypeCasting 类型转换

发表于 2014-08-07 | 分类于 Swift , TypeCasting , 类型转换 | 阅读次数:
字数统计: 506 字 | 阅读时长 ≈ 3 分钟

TypeCasting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

//swift 提供了 is 和 as 两个操作符,用以检测值的类型或者转换它的类型
class MyBasic{
var name : String
init (name : String){
self.name = name
}
}

class MyFriend : MyBasic {
var level = 9
}

class MySelf : MyBasic {
var height = 9
}
阅读全文 »

《浅入浅出Swift》Optional Chaining 可选链

发表于 2014-08-06 | 分类于 Swift , Optional Chaining , 可选链 | 阅读次数:
字数统计: 111 字 | 阅读时长 ≈ 1 分钟

####Optional Chaining

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

//可选型是!?

struct MyName{
var name:String = "nicai"
}
struct MyInfo{
var myName : MyName? = MyName()
}
class MyClass{
var structInstance:MyInfo? = MyInfo()
}
var myInstance = MyClass()
println("myInstance = \(myInstance)")

//使用一连串的可选值,叫做可选链
//在可选链中,任何一个环节解析失败(nil),那么整个可选链的结果为nil
if let name = myInstance.structInstance?.myName?.name{
println(name)
}else{
println("nil")
}
阅读全文 »

《浅入浅出Swift》Automatic Reference Counting 自动引用计数

发表于 2014-08-05 | 分类于 Swift , ARC , 自动引用计数 | 阅读次数:
字数统计: 684 字 | 阅读时长 ≈ 3 分钟

####ARC

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

//ARC机制会跟踪每一个实例正在被多少属性,常量和变量所引用,只要这个实例的引用数不为0,那么这个实例就不会被销毁。那么它的deinit也不会被调用
//实例之间的循环引用是怎么发生的。如果消除循环引用导致内存泄露

class Person {
let name : String
init (name : String) {
self.name = name
println("\(name) is being initialized")
}
deinit {
println("\(name) is being deinitialized")
}
}

var reference1:Person?
var reference2:Person?
var reference3:Person?

reference1 = Person(name: "John Appleseed")
reference2 = reference1
reference3 = reference1

reference1 = nil
reference2 = nil
reference3 = nil

}

func swiftARCMethodTwo() {
//Strong Reference Cycles Between Class Instances


class Person {
let name : String
init (name : String){
self.name = name
}

var apartment: Apartment?
deinit {
// apartment = nil;
println("\(name) is being deinitialized")
}
}

class Apartment{
let number : Int
init (number : Int){
self.number = number
}
weak var tenant : Person?
deinit {
// tenant = nil;
println("Apartment #\(number) is being deinitialized")
}
}
//上2个类分别都有另一个类的optional类型的变量。结果就是互相持有对方
//在ARC中,当把John和number73都赋值为nil时,看似断了2个引用,但在实例中,还有apartment和tenant2个引用没断,于是,把释放写入deinit中
//deinit并不会被调用。因为ARC中只有引用计数到0时,deinit才会被调用
//为了解决上面的循环引用,引入了关键字weak
var john : Person?
var number73 : Apartment?
john = Person(name: "John Appleseed")
number73 = Apartment(number: 73)

john!.apartment = number73
number73!.tenant = john

// john number73
// \strong \strong
// name:John Appleseed --->strong number:73
// apartmen<Apartment 实例> <---weak tenant:<Person 实例>
//引入了weak引用不会阻止ARC回收实例,也就是说,一个实例,如果没有被强引用,再多的引用持有它的话,它依然可以被释放。


//无主引用,Unowned References
//weak是给optional类型用的(!?),而unowned是给非可选型用的
class Customer{
let name :String
var card : CreditCard?
init (name : String){
self.name = name
}

deinit {
println("\(name) is being deinitialized")
}
}
class CreditCard{
let number : UInt64
unowned let customer : Customer
// weak var customer : Customer?
init (number : UInt64 , customer : Customer){
self.number = number
self.customer = customer
}
deinit {
println("Card #\(number) is being deinitialized")
}
}
var johnOne : Customer?
johnOne = Customer(name: "John Appleseed")
johnOne!.card = CreditCard(number: 1234_5678_9012_3456, customer: johnOne!)


//闭包导致的循环强引用,Strong Reference Cycles for Closures
/*
class HTMLElement{
let name: String
let text: String?
//闭包
lazy var asHTML: () -> String = {
// [unowned self] in
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}

init(name: String, text: String? = nil) {
self.name = name
self.text = text
}

deinit {
println("\(name) is being deinitialized")
}
}
*/

阅读全文 »

《浅入浅出Swift》Deinitialization 析构过程

发表于 2014-07-31 | 分类于 Swift , Initialization , 析构过程 | 阅读次数:
字数统计: 393 字 | 阅读时长 ≈ 2 分钟

####Initialization

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

//析构过程是构造过程的逆向过程,当一个类的实例被释放的时候,在内存中消失前,析构器会被调用
//swift通过ARC管理内存。


//由于swift是ARC管理内存,所以析构过程已经不是那么重要了
class MyClass{
var myNum = 0
init (){
myNum = 1
}

deinit {
myNum = 0
println("myNum \(myNum)")
}
}

var myClass = MyClass()
println("myClass.myNum = \(myClass.myNum)")
// myClass = nil

//Deinitializers in Action
struct Bank {
//在银行的金币数
static var coinsInBank = 10_000
//出售金币
static func vendCoins(var numberOfCoinsToVend:Int)->Int{
println("numberOfCoinsToVend = \(numberOfCoinsToVend)")
println("coinsInBank = \(coinsInBank)")
numberOfCoinsToVend = min(numberOfCoinsToVend, coinsInBank)
println("numberOfCoinsToVend = \(numberOfCoinsToVend)")
coinsInBank -= numberOfCoinsToVend
return numberOfCoinsToVend
}

//收到金币
static func receiveCoins(coins:Int){
coinsInBank += coins
}
}

class Player{
//硬币钱包
var coinsInPurse : Int
//初始化
init (coins: Int){
coinsInPurse = Bank.vendCoins(coins)
println("Player.init.coinsInPurse = \(coinsInPurse)")
}
//赢得的钱币
func winCoins(coins:Int){
coinsInPurse += Bank.vendCoins(coins)
}
//析构过程
deinit{
Bank.receiveCoins(coinsInPurse)
}
}

//生成一个player,初始化银行出售金币100枚
var playerOne : Player? = Player(coins:100)
println("A new player has joined the game with \(playerOne!.coinsInPurse) coins")
// prints "A new player has joined the game with 100 coins"
println("There are now \(Bank.coinsInBank) coins left in the bank")
// 银行剩余9900 coins

playerOne!.winCoins(2_000)
println("PlayerOne won 2000 coins & now has \(playerOne!.coinsInPurse) coins")
//赢了2000枚,加上前面的100枚
println("The bank now only has \(Bank.coinsInBank) coins left")//银行剩余7900
playerOne = nil
println("The bank now only has \(Bank.coinsInBank) coins left")//银行剩余10000枚
阅读全文 »

《浅入浅出Swift》Initialization 构造过程

发表于 2014-07-26 | 分类于 Swift , Initialization , 构造过程 | 阅读次数:
字数统计: 1,816 字 | 阅读时长 ≈ 8 分钟

####Initialization

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

//生成class,struct,enum等实例的准备过程叫做构造过程。
//通常定义一个方法来完成,这个方法叫做,构造器。
//它的逆向过程,叫做析构器,用于在实例被释放前做一些清理工作和自定义的处理

//为存储属性设置初始值,必须为所有属性服赋特点的初始值
//在定义存储型属性时直接给个初始值,否则就必须在init里面指定一个初始值
//上述方法都不会触发存储型属性的坚挺者行为

//Initializers
struct Fahrenheit{
var temperature: Double
init (){
temperature = 32.0
}
}
var f = Fahrenheit()
println("The default temperature is \(f.temperature)° Fahrenheit")
// prints "The default temperature is 32.0° Fahrenheit"
//直接定义
struct FahreheitTwo{
var temperature: Double = 1.0
}

//Customizing Initialization
//Initialization Parameters
struct Celsius{
var temperatureInCelsius:Double = 0.0
init (fromFahrenheit fahrenheit:Double){
temperatureInCelsius = (fahrenheit - 32.0) / 1.8
}
//可以定义多个构造器
init (fromKelvin kelvin:Double){
temperatureInCelsius = kelvin - 273.15
}
}
//沸点
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
//冰点
let freezingPointOfWater = Celsius(fromKelvin: 273.15)


//本地和外部参数名称,Local and External Parameter Names
//下面的例子定义了一个结构称为颜色,和三个常量属性称为红、绿、蓝。这些属性存储一个值在0.0和1.0之间显示红、绿、蓝的颜色。
//颜色提供了一个初始化器和三个适当命名的参数类型
struct Color{
let red = 0.0 ,green = 0.0 ,blue = 0.0
init (red:Double, green:Double, blue:Double){
self.red = red
self.green = green
self.blue = blue
}
}
let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)
// let veryGreen = Color(0.0,1.0,0.0)
// this reports a compile-time error - external names are required

//可选属性类型,Optional Property Types
class SurveyQuestion{
var text:String
var response:String?//<--- ?
init (text:String){
self.text = text
}
func ask(){
println(text)
}
}
let cheeseQuestion = SurveyQuestion(text:"Do you like cheese?")
cheeseQuestion.ask()
cheeseQuestion.response = "Yes,I do like cheese."
println(cheeseQuestion.response)//输出结果

//在初始化期间修改常量属性,Modifying Constant Properties During Initialization
class SurveyQuestionTwo {
let text:String
var response:String?
init (text :String){
self.text = text
}

func ask() {
println(text)
}
}
let beetsQuestion = SurveyQuestion(text: "How about beets")
beetsQuestion.ask()
beetsQuestion.response = "I also like beets.(But not with cheese.)"


//默认初始化,Default Initializers
class ShoppingListItem {
var name:String?
// var quantity = 1 //Xcode6 beta 3 bug
var purchased = false
}

//Memberwise Initializers for Structure Types
struct SizeTest {
var width = 0.0, heigh = 0.0
}
let twoByTwo = SizeTest(width: 2.0, heigh: 2.0)
struct MyShruct {
var name = "1", number = 2
}
let myStruct = MyShruct(name: "Hello", number: 2)


//值类型的构造器代理Initializer Delegation for Value Types
//init还能调用其他的构造器作为构造过程的一部分。这的过程叫做构造器代理
//值类型(struct,enum)并不支持继承,所以,他们构造器代理与类的构造器代理规则和形式有所区别
struct Size{
var width = 0.0 ,height = 0.0
}
struct Point {
var x = 0.0,y = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
init (){}


init (origin:Point, size:Size){
self.origin = origin
self.size = size
}

init (center:Point, size:Size){
let originX = center.x - (size.width / 2)
let originY = center.y - (size.height / 2)
self.init(origin:Point(x: originX, y: originY),size:size)
}

}
//Rect中有3个构造器,第一个是空{},当这个构造器被调用的时候:
// let rect = Rect()
// println(rect)//origin (0.0 ,0.0) ,size (0.0, 0.0)
let originRect = Rect(origin: Point(x:2.0,y:2.0), size: Size(width: 5.0, height: 5.0))
let centerRect = Rect(center: Point(x: 4.0, y: 4.0), size: Size(width: 3.0, height: 3.0))

//类继承和构造过程, Class Inheritance and Initialization
//swift提供了2种构造器,以确保所有的属性都能被初始化,指定构造器 和 便利构造器
//https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-XID_265
//构造器调用链
//指定构造器和便利构造器的调用关系,swift指定了3条规则
//1,构造器代理必须调用他的直接父类的指定构造器
//2,便利构造器必须调用它同一个类中定义的其他构造器
//3,便利构造器的结尾部分必须调用一个指定构造器

//指定构造器必须总是向上代理 向上代理的意思就是调用父类指定的构造器
//便利构造器必须总是横向代理 横向代理的意思就是调用它自己类内的构造器

//指定构造器和便利构造器,Designated Initializers and Convenience Initializers
//指定构造器 <-- 便利构造器 <-- 便利构造器 【一个类】
// ^
// |
// \
//便利构造器 ->指定构造器 <-- 便利构造器 【一个类】


//两段式构造过程,Two-Phase Initialization
//swift类包含2个阶段
//1,每个存储型属性通过她们自己的类构造器来设置初始值
//2,每个存储型属性都可以进一步设置他们定制化的初始化
//so两段式构造过程,就是告诉我们,使用变量,常量之前要确保它被定义并且被初始化了
var csjNumA:Int = 1
var csjNumB:Int = 2
func csjNumFunc(){
csjNumA = csjNumB
}

//构造器的继承和重写,Initializer Inheritance and Overriding
//swift中,子类不会默认的继承父类的构造器。但是有时觉得父类的构造器功能不够强大,这个时候就要在子类中重写构造器,以达到目的。
//重写一个指定构造器, 写完之后要调用父类构造器
//重写一个便利构造器,必须要调用这个类中的其他指定构造器
//构造器重写不需要添加 override关键字

//自动构造器的继承,Automatic Initializer Inheritance
//swift构造器继承机制要满足2点:
//1,如果子类没有定义任何指定构造器,它将自动继承所有父类的指定构造器
//2,如果子类中定义了所有父类的指定构造器的实现,它将会自动继承所有父类的便利构造器


//指定构造器和便利构造器的语法,Syntax for Designated and Convenience Initializers
//指定构造器
//init(参数){
// 函数体
//}

//便利构造器
//convenience init(参数){
// 函数体
//}
//convenience型的构造器,只能调用它自己这个类中的非convenience


//指定和便利构造器初始化,Designated and Convenience Initializers in Action


//用闭包或者函数设置属性的默认值,Setting a Default Property Value with a Closure or Function
class MyClass{
var myNumbers:[Int] = {
var tempNum = [Int]() //生成一个临时的数组,在闭包最后给myNumbers赋值
for i in 1...10{
tempNum.append(i) //添加元素
}
return tempNum //闭包的返回值
}() //()表示myNumbers是闭包的返回值,要不然就成了闭包这个函数了

func getNumbers()->[Int]{
return myNumbers
}
}
let myClass = MyClass()
println("myClass.getNumbers = \(myClass.getNumbers())")//获取到了MyClass的myNumbers数组
阅读全文 »

《浅入浅出Swift》Inheritance 继承

发表于 2014-07-19 | 分类于 Swift , Inheritance , 继承 | 阅读次数:
字数统计: 585 字 | 阅读时长 ≈ 3 分钟

####Inheritance

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

//一个类可以从其他类继承方法,属性以及一些特征。被集成的类叫父类,那另一个就是子类
//Vehicle是一个基类
class Vehicle {
var numberOfWheels : Int
var maxPassengers : Int
func description() -> String{
return "\(numberOfWheels) wheels; up to \(maxPassengers) passengers"
}

init (){
numberOfWheels = 0
maxPassengers = 1
}
}

//继承
class Car : Vehicle{//继承的语法
//swift既不会继承父类的初始化,也不会自动执行父类的初始化方法
init(){//MyCar 类初始化方法
super.init()
numberOfWheels = 4 //从Vehicle继承过来的属性
}
}

class CarTwo : Vehicle{
init (){
super.init()
numberOfWheels = 4
maxPassengers = 5
}
}
let carTwo = CarTwo() //执行CSJInherTwo的init方法
println("inher = \(carTwo.description())")//description从父类继承来的,在CSJInherTwo并没有定义

//方法重写 Overriding
class CarThree : Vehicle{
var speed : Double = 0
init(){
super.init()
numberOfWheels = 4
maxPassengers = 5
}

override func description() -> String {
return super.description() + "now speed is \(speed) mph"//只是在父类的description输出内容后面加字
}
}
let carThree = CarThree()
println("carThree : \(carThree.description())")

//也可以对父类的set和get方法进行重写,但是必须写明属性名和属性类型
//这样重写是完全忽略这个属性在父类中定义成用于计算或者用于存储的,在子类中提供的set和get方法,可以把父类的“只读”型属性重写成“读写“属性
//Overriding Property Getters and Setters
class CarSpeedLimited : CarThree{
override var speed: Double {
get {
return super.speed
}
set{
println("car must speed limited lower than 100 mph")
super.speed = min(newValue, 40.0)
}
}
}
let limitedCar = CarSpeedLimited()
// limitedCar.speed = 60.0 //貌似Xcode6 beta3 bug了 报错Ambiguous use of 'speed'
println("SpeedLimitedCar: \(limitedCar.description())")

//overriding property observers
//不能为一个不能改变值的属性重写属性的监听者,比如继承来的只读类型属性
//不能为一个属性同时加入set方法和监听者
/*
class AutomaticCar : CarThree{
var gear = 1
override var speed : Double{
didSet{
// gear = 1
gear = Int (speed / 10.0) + 1
}
}
override func description() -> String {
return super.description() + "in gear \(gear)"
}
// init() {
// super.init()
// }

}
*/


//swift防止重写 使用@final关键字
class FinalTest {
var numberOfWheels : Int
var maxPassengers : Int
@final func nicai()->String{
return "你猜"
}
init(){
numberOfWheels = 0
maxPassengers = 1
}
}
阅读全文 »

《浅入浅出Swift》Subscripts 下标

发表于 2014-07-19 | 分类于 Swift , Subscripts , 下标 | 阅读次数:
字数统计: 476 字 | 阅读时长 ≈ 2 分钟

Subscripts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//下标允许我们为class,struct,enum定义下标,以更便捷的方式访问属性。
//比如,Array和Dictionary都是结构和改写struct中保存的数据。
//一个类型中可以定义多种下标访问方式(重载)

//下标可以定义“读写”,“只读”型,通过定义一组操作完成的,这与之前的计算属性的setter和getter是一样的

//下标语法,Subscript Syntax
//读写型
/*
subscript(index:Int) -> Int {
get {
// return an appropriate subscript value here
}
set(newValue) {
// perform a suitable setting action here
}
}
*/

阅读全文 »

《浅入浅出Swift》Methods 方法

发表于 2014-07-16 | 分类于 Swift , Methods , 方法 , 实例方法 , 类方法 | 阅读次数:
字数统计: 1,041 字 | 阅读时长 ≈ 5 分钟

####Methods

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

//实例方法,Instance Methods
//swift会为方法的第一个参数只提供函数内部使用的名字,从第二个参数开始,既可以外部用,也可以内部用
class CsjClass{
var myNum : Int = 0
func increaseNum(base:Int, numberOfTimes:Int){
myNum += base * numberOfTimes
}
}
var csjClass = CsjClass()
//第二个参数开始,会自动提供一个外部使用变量名
csjClass.increaseNum(10, numberOfTimes: 8)//******

//func想为外部提供一个变量名的话有2种做法
//func csjFunc(value paramA:Int){......} //value是给外部使用的名字,paramA是内部使用
//func csjFunc(#paramA:Int) {......} //paramA 既是外部用的,也是内部用的
//csjClass类的实例方法中,相当于,从第二个参数开始,swift自动为我们提供了"#"的功能,不需要我们写#
class NewCsjClass{
var myNum : Int = 0
//"_ "这样swift就不再会自动提供外部使用名字了
func increaseNum(base:Int, _ numberOfTimes:Int){
myNum += base * numberOfTimes
}
}
var newCsjClass = NewCsjClass()
newCsjClass.increaseNum(10, 8)//******


//self属性,The self Property
//每个实例,都有一个属性用于表示它自己这个实例,这个属性叫做self
class CSJSedClass {
var num : Int = 0
//传入参数名叫num,设置属性也叫num的时候,到底是传入的值,还是实例的属性,我们为实例属性前面加了self,表示这个是实例自己的属性
func setNume(num:Int){
self.num = num
}
}

//变化(修改)方法,修改值类型的实例方法,Modifying Value Types from Within Instance Methods
//上述都是class的情况,对于struct,enum这样的值传递类型,却不能使用实例方法来改变属性的值
struct CSJPoint{
var x = 0, y = 0
mutating func moveByXY(deltaX: Int, y deltaY:Int){
x += deltaX
y += deltaY
}
}
var csjPoint = CSJPoint()
csjPoint.moveByXY(3, y: 4)
println("x:\(csjPoint.x),y:\(csjPoint.y)")
//在struct,enum里使用mutating关键字,达到class里一样的效果
//如果x,y是let就不能使用,不能改变常量

//在mutating方法中,给self赋值
struct CSJTwoPoint{
var x = 0 ,y = 0
mutating func changeSelf(deltaX:Int, y deltaY:Int){
self = CSJTwoPoint(x:deltaX,y:deltaY)
}
}
var csjTwoPoint = CSJTwoPoint()
csjTwoPoint.changeSelf(3,y:4)
println("x:\(csjTwoPoint.x),y:\(csjTwoPoint.y)")
//达到了改变csjTwoPoint中x和y的目的,给self赋值的方法,却是生成了一个新的CSJTwoPoint实例(内部做了内存释放工作)
enum CSJStateMachine{
case None,Init,Run,Deinit
//实例方法
mutating func nextState(){
switch self{
case None:self = Init
case Init:self = Run
case Run:self = Deinit
case Deinit:self = None
}
}
}
var csjStateMachine = CSJStateMachine.None
csjStateMachine.nextState() //self变成Init
println(csjStateMachine == CSJStateMachine.Init)//ture
csjStateMachine.nextState()
println(csjStateMachine == CSJStateMachine.Run)//ture
//状态机的状态切换代码可以直接写在enum的定义中

//类型方法,Type Methods
//上面地方都是实例方法,它们都是针对某一个实例进行操作的,而类方法,是对这个类型的。(static和class)
class TestClass{
class var computedProperty : Int {
return 0
}
class func someMethod(){
//这才是一个类方法
}
}
//因为类里面的类型属性只能用于计算,不能保存数据,所以类的类方法,暂时不适合写一个可以跑起来的例子,应该结合struct或者enum,才可以写
struct LevelTracker{//等级跟踪器
static var highestUnlockedLevel = 1//类型属性,所有的实例共用这个值
//类方法
static func unlockLevel(level: Int){
if level > highestUnlockedLevel{
highestUnlockedLevel = level
}
}
//类方法
static func levelIsUnlocked(level : Int) -> Bool{
return level <= highestUnlockedLevel
}
var currentLevel = 1

mutating func advanceToLevel(level:Int) ->Bool{
if LevelTracker.levelIsUnlocked(level){
currentLevel = level
return true
}else{
return false
}
}
}

class Player {
var tracker = LevelTracker()
let playName : String
func completedLevel(level:Int){
LevelTracker.unlockLevel(level+1)//调用结构体类方法
tracker.advanceToLevel(level+1) //调用了tracker的实例advanceToLevel
}

init(name:String){
playName = name
}
}
var player = Player(name:"World")
player.completedLevel(1)//调用后 tarcker的highestUnlockedLevel变成2
println("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")

var player2 = Player(name:"Kitty")
if player2.tracker.advanceToLevel(6){
println("player is not on level 6")
}else{
println("level 6 has not yet been unlocked")
}
阅读全文 »

《浅入浅出Swift》Properties 属性

发表于 2014-07-15 | 分类于 Swift , Properties , 属性 | 阅读次数:
字数统计: 1,207 字 | 阅读时长 ≈ 6 分钟

####Properties

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192


//存储属性,Stored Properties
//下面的例子定义了一个称为FixedLengthRange结构,描述了一个范围的整数范围长度,一旦创建不能改变:
struct FixedLengthRange{
var firstValue:Int
let length:Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue:0, length: 3)
//the range represents integer values 0,1 and 2
rangeOfThreeItems.firstValue = 6
//the range now represents integer values 6,7 and 8

//存储属性不变结构的实列,Stored Properties of Constant Structure Instances
//如果您创建一个结构的实例,并将该实例分配给一个常量,您不能修改实例的属性,即使他们被声明为变量属性:
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
//this range represents integer values 0,1,2 and 3
// rangeOfFourItems.firstValue = 6 //<---error

//懒惰的存储属性,Lazy Stored Properties
class DataImporter{
var fileName = "data.text"
}
//xcode6 beta3 有点问题
/*
class DataManager {
@lazy var importer = DataImporter()
var data = [String]()
}
let manager = DataManager()
manager.data += "Some data"
manager.data += "Some more data"
println("manager.data = \(manager.data)")
println(manager.importer.fileName)
*/



//用于计算的属性,Computed Properties
//这种属性本身并不会保存数值,而是提供了一个getter和一个可选的setter方法,来间接的设置其它属性的值。
//点
struct Point{
var x = 0.0,y = 0.0
}
//尺寸
struct Size {
var width = 0.0, height = 0.0
}
struct Rect {
//在Rect结构体中有一个center属性,还有一个origin属性和size属性
//而center属性是完全可以通过origin和size计算得到,并不需要存储
//反过来,只移动center的话,那么要根据center点和size值就可以计算出新的origin属性的的值。
//所以center不需要保存什么值,用于计算而非用于存储的属性
//起始点
var origin = Point()
var size = Size()
var center : Point {
get {
let centerX = origin.x + (size.width/2)
let centerY = origin.y + (size.height/2)
return Point(x: centerX, y: centerY)
}
//为set提供了一个参数newCenter,而这个参数可以被省略,
//未省略
// set (newCenter){
// origin.x = newCenter.x-(size.width/2)
// origin.y = newCenter.y-(size.height/2)
// }
//省略
set {
origin.x = newValue.x-(size.width/2)
origin.y = newValue.y-(size.height/2)
}
}

}
var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x:15.0,y:15.0)
println("square.origin is now at (\(square.origin.x),\(square.origin.y))")
// prints "square.origin is now at (10.0, 10.0)"

//Shorthand Setter Declaration
struct AlternativeRect {
var origin = Point()
var size = Size()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
//省略参数记为newValue
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}

//只读Read-Only Computed Properties
//只读用于计算的属性,我们可以省掉get
struct Cuboid{
var width = 0.0, height = 0.0, depth = 0.0
var volume : Double{
return width*height*depth
}
}
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
println("the volume of fourByFiveByTwo is \(fourByFiveByTwo)")
// prints "the volume of fourByFiveByTwo is 40.0"

//属性观察员Property Observers
//是在它监控的那个属性被设置时触发的,即使这个属性的新值和原值是一样的
//willSet 在属性被设置新值,但还没有保存的时候,被调用
//didSet 在属性保存了新值后立即被调用
//属性第一次被初始化的时候不会被调用
class StepCounter{
//闭包
var totalSteps : Int = 0{
willSet(newTotalSteps){
println("About to set totalSteps to \(newTotalSteps)")
}
didSet{
//swift提供oldValue
if totalSteps > oldValue{
println("Added \(totalSteps-oldValue) steps")
}
}

}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
//set totalSteps to 200
//added 200 steps
stepCounter.totalSteps = 360
//set totalSteps to 360
//added 160 steps
stepCounter.totalSteps = 896
//set totalSteps to 896
//added 536 steps
class TestClass{
var num:Int=0{
willSet{
println("testClass willSet = \(num)")
}
didSet {
num = oldValue//赋值为0,所有输出为0
println("testClass didSet = \(num)")
}
}
}
var testClass = TestClass()
testClass.num = 8
println("testClass = \(testClass.num)")


//全局常量、变量,也都可以设置用于计算的属性,Global and Local Variables
var Q_myNum = 0
var Q_myValue:Int{
return Q_myNum
}
println("Q_myNum = \(Q_myValue)")

//类型属性,Type Property Syntax
//类似c/c++中的静态变量,所有实例共享一份拷贝,而不是每一个实例都有一份
//swift依然用了static这个关键字,类中用class关键字
struct SomeStructure{
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
//return an Int value here
return 0
}
}
enum SomeEnumeration{
static var storedTypeProperty = "Some value."
static var computedTypeProperty : Int{
//return an Int value here
return 0
}
}
class SomeClass{
class var computedTypeProperty: Int{
return 0
}
}

//查询和设置类型属性Querying and Setting Type Properties
println("SomeClass.computedTypeProperty = \(SomeClass.computedTypeProperty)")
println(SomeStructure.storedTypeProperty)
SomeStructure.storedTypeProperty = "Another value."
println(SomeStructure.storedTypeProperty)
阅读全文 »
123…9

87 日志
161 分类
11 标签
GitHub E-Mail Twitter
© 2013 — 2021 iceesj
全站共38.1k字
/
访客数:
0%