Swift:概念解释
持续更新中...
github:Swift基础实例
github:SwiftBasicTableView
type methods
被特定类型的实例 instance
调用的方法叫实例方法 instance methods
,类似于 OC
的对象方法(减号方法
)。而被类型自己调用的方法叫做类型方法 type methods
,类似 OC
的类方法(加号方法
)。你可以在方法关键字 func
前加上关键字 static
来表示这些方法是 type methods
。在类中(Classes
),也可以在func
前加 class
关键字表示允许他的子类继承父类的这个方法的实现。
value type
某一个类型的值,当它被分配给某个变量(variable
)或者常量(constant
),或者被传递给一个函数时,它的值是被拷贝的(可以打印它们的内存地址进行比较),那么这种类型称为值类型value type
。在 Swift
中,所有的基本类型都是都是 value type
,比如 integers
, floating-point numbers
, Booleans
, strings
, arrays
and dictionaries
,structures
,enumerations
memberwise initializer
结构体类型(structure
)如果它 没有 自定义一个自己的构造器的话,会自动接收一个成员构造器memberwise initializer
。和默认构造器不同,在存储属性没有被设置默认值的情况下,结构体依然接收一个memberwise initializer
。因此,memberwise initializer
是初始化结构体对象的成员属性的捷径:
struct SomeSize {
//var width = 0.0, height = 0.0
var width :Double?
var height:Double?
}
// 不管width和height是否被初始化,SomeSize都会自动接收一个带有两个参数width和height的成员构造器
SomeSize() //默认构造器
let someSize = SomeSize(width: 3.0, height: 2.0)
Inout Parameter
一般的,函数中的变量参数(variable parameters
),只能在函数体里进行修改。如果你想把这种修改持久化,就是在函数调用之后,对变量参数的修改,也会影响到函数外被传进来的变量。你需要把这个参数定义为in-out parameter
:在参数名前面加上关键字 inout
。in-out parameter
的含义就是有一个值被传进(in
)函数,被函数修改之后,又返回出去(out
),并替换原来的值。一个变量被当做参数传进函数时,可以在变量名前加上&
,表示这个变量可以被函数改变:
func swapTwoInts(inout a:Int, inout _ b:Int) {
let tempInt = a
a = b
b = tempInt
}
var someInt = 3,someIntTwo = 5
swapTwoInts(&someInt, &someIntTwo)
print(someIntTwo) // 3
- 把两个值
someInt
和someIntTwo
互换
Failable initializer
当初始化一个类(class
),结构体(structure
)或者枚举(enumeration
)的时候,可以允许初始化失败,这个失败可能是由于某些参数不合法,或者某些参数的缺失,或者其他的一些情况导致的。这个允许失败的构造器称为可失败构造器 failable initializer
,在关键字 init
后面加上问号?
,来表示这个构造器 init?
。
比如,给某个菜添加信息时,要求,有三个属性:名称name:String
,评分rating:Int
和图片photo:UIImage
,其中,name
rating
不为空且rating > 0
, photo
可以为空,我们用模型 Meal
来存储这些属性,Meal
的 failable initializer
如下:
init?(name: String, photo: UIImage?, rating: Int) {
self.name = name
self.photo = photo
self.rating = rating
if name.isEmpty || rating < 0 {
return nil
}
}
- 当
name
为空,或者rating < 0
时,就会初始化失败,此时可以返回nil
Downcasting
类似于类型转换。通常,某个确定的类,其类型的常量或变量,会引用场景(scene
)背后的一个子类(比如类A)的实例,这样,你可以把这个常量或变量向下转换(downcast
)为子类类型A。可以用操作符 as!
or as?
。as!
是强制类型转换,只有当你非常确定这样做可以成功时,才可以使用,否则,不成功会引起 crash
。as?
如果转换不成功,则会返回 nil
。所以当你不确定向下转换是否能成功时,使用as?
。比如,从相册选择一个图片时,可以这样得到类型为 UIImage
的图片对象:
let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
Reference Types
Class
和Closure
是 reference types
。和 value types
不同,reference types
并不是被拷贝的,而是通过一个引用来访问相同的实例,无论是他们被分配给一个变量或常量或者被传递给一个函数。我们假设类 VideoMode
有个属性 frameRate: Float
,来查考引用
let tenMode = VideoMode()
tenMode.frameRate = 20.0
let alsoTenMode = tenMode
alsoTenMode.frameRate = 30.0
print("The frameRate now is \(tenMode.frameRate)") // "The frameRate now is 30.0"
实例 tenMode
被分配给了另外一个实例 alsoTenMode
,由于类是reference types
,因此,这两个实例都指向相同的 VideoMode instance
.
Identical to(===) Not identical to(!==)
因为类 class
是引用类型,所以多个常量和变量就可以访问 场景(scene
)后的同一个实例(类的实例对象)。那么,怎么分辨两个实例或者变量引用的是同一个实例(类的实例对象)呢?可以使用下面两种操作符来区分:
- Identical to (===)
- Not identical to (!==)
我们可以比较上面的类 VideoMode
的两个实例tenMode
和alsoTenMode
if tenMode === alsoTenMode {
print("tenMode and alsoTenMode refer to the same VideoMode instance.")
// "tenMode and alsoTenMode refer to the same VideoMode instance."
}
Properties
关于 Strored Properties 、Lazy Stored Properties、Compute Properties 请参考 Properties 这一章节