Int和CPU架構有關
在32位CPU上(iphone5及以前)是Int32,64位上(5s及以後)為Int64。UInt同理。
可選鏈式呼叫
可選鏈式呼叫失敗時,等號右側的程式碼不會被執行
func createAddress() -> Address {
print("Function was called.")
return Address()
}
john.residence?.address = createAddress() // 不會輸出列印
@autoclosure
autoclosure可以把表示式轉化為閉包。
func judgeLog(@autoclosure predicate: () -> Bool, msg: String) {
if predicate() {
print(msg)
}
}
judgeLog(2>1, msg: "2 > 1 is right")
assert & fatalError
assert是Debug時才起效,Release下不起效。而fatalError無論哪種情況都起效。可以按照需求來選擇錯誤奔潰處理。
mutating
mutating修飾方法,用在struct,enum這些值型別中,他們的方法中修改屬性必須使用mutating。
infix, prefix, postfix
在新增自定義操作符時,分別加上infix表示中位符 prefix前位符 postfix後位符。
infix operator +* {
associativity none //結合律,
precedence 160 //優先順序,乘除為150,加減為140
}
// 過載+*
func +* (left: Int, right: Int) -> Int {
return (left * right + left + right)
}
inout
函式的引數預設是let,如果有時候需要修改傳入的變數的值,需要新增inout關鍵字。
Designated & Convenientce & Required
designated初始化方法就是最普通的init方法。designated方法必須確保所有成員物件被初始化了。
初始化方法中依賴其他初始化方法,必須使用convenience。若父類實現了convenicence init那麼子類可以直接使用父類這個方法來初始化。
required是強制子類必須重寫的關鍵字。
初始化方法返回nil
init後加”?”或”!”允許在初始化中返回nil來例項化optional物件。
型別混合
let mixed1: [Any] = [1, "two", 3.0]
let mixed2 = [1, "two", 3.0] // [NSObject]
enum IntOrString {
case IntValue(Int)
case StringValue(String)
}
let mixed3 = [IntOrString.IntValue(1), IntOrString.StringValue("haha")]
dynamicType獲取動態型別
protocol Copyable {
func copy() -> Self
}
class MyClass: Copyable {
var num: Int
required init(num: Int) {
self.num = num
}
func copy() -> Self {
let result = self.dynamicType.init(num: self.num)
return result
}
}
多重optional
let aNil: String? = nil
let bNil: String?? = aNil
let cNil: String?? = nil // bNil不等於cNil
lldb除錯命令
執行時,lldb除錯直接使用po指令可以列印物件的值 (po = print object)
使用bt可以列印出現場堆疊資訊
使用fr v xxx列印楨資訊,”fr v -R xxx”來列印多重變數資訊
map方法
let arr = [1,2,3]
let doubled = arr.map({
$0 * 2
})
print(doubled) // [2, 4, 6]
let num: Int? = 6
let result1 = num.map {
$0 * 2
}
print(result1) // Optional(12)
where用法
let name = ["li ming", "wang hao", "xiao bai"]
name.forEach { (_name) in
switch _name {
case let x where x.hasPrefix("xiao"):
print("[(x)] is my family")
default:
print("[(_name)] is not my family")
}
}
let score: [Int?] = [99, 100, nil, 60]
score.forEach {
if let s = $0 where s == 100 {
print("you are so smart!")
}
}
在擴充中也可以這麼使用
extension Array where Element: Integer {
// ...
}
型別方法
例項方法是被型別的某個例項呼叫的方法。你也可以定義型別本身呼叫的方法,這種方法就叫做型別方法。只需要在func前新增class。型別方法內部self指向這個型別本身,而不是型別的某個例項。
class MyClass {
class func method() {}
}
MyClass.method()
例項方法的動態呼叫
class MyClass {
func method(number: Int) -> Int {
return number + 1
}
}
let f = MyClass.method // 等價於let f = { (obj: MyClass) in obj.method }
let object = MyClass()
let result = f(object)(1) // 2
如果加入過載和類方法:
class MyClass {
class func method(number: Int) -> Int { // #1
return number
}
func method(number: Int) -> Int { // #2
return number + 1
}
func method(numberA: Int, numberB: Int) -> Int { // #3
return numberA + numberB
}
}
let f0 = MyClass.method // 等價於型別方法 #1
let f1: Int -> Int = MyClass.method // 等價於f0
let f2: MyClass -> Int -> Int = MyClass.method // #2
let f3: MyClass -> (Int, Int) -> Int = MyClass.method // #3
let object = MyClass()
let result0 = f0(1) // 1
let result1 = f1(1) // 1
let result2 = f2(object)(1) // 2
let result3 = f3(object)(2,2) // 4
條件編譯
#if <condition>
// ...
#elseif <condition>
// ...
#else
// ...
#endif
條件可以是os(OSX)/os(iOS),arch(x86_64)/arch(arm)/arch(arm64)/arch(i386)
也可以是自定義的一個條件變數:Build Settings->Swift Compiler->Custom Flags新增-D CONDITION_NAME
可選介面
// # 1 使用objective-c方式
@objc protocol OptionalProtocol {
optional func optionalMethod()
func necessaryMethod()
}
// # 2 使用介面擴充
protocol OptionalProtocol {
func optionalMethod()
func necessaryMethod()
}
extension OptionalProtocol {
func optionalMethod() {}
}
求隨機數
使用arc4random_uniform(arc4random在32位iPhone上有時程式奔潰)
// # 1
let maxValue: UInt32 = 10
print(Int(arc4random_uniform(maxValue)) + 1)
// # 2
func randomInRange(range: Range<Int>) -> Int {
let count = UInt32(range.endIndex - range.startIndex)
return Int(arc4random_uniform(count)) + range.startIndex
}
for _ in 1...10 {
print(randomInRange(1...10))
}