Swift 3.0基礎(chǔ)語法

Swift筆記

Any AnyObject NSObject

Int Double String struct都是結(jié)構(gòu)體

  1. Any : 一個協(xié)議聲明
  2. AnyObject : 一個具體的協(xié)議向拆,協(xié)議里面沒有內(nèi)容鹃操,默認(rèn)情況下汞斧,所有的類答姥,都遵循了這個協(xié)議
  3. NSObjectNSObject

條件判斷

swift中沒有非零即真和零為假的說法,只有嚴(yán)格的Bool(true/false)

1. if的使用

let a = 1
if a == 1 {
    print("test")
}else if  a == 2{
    print("sss")
}else {
    print("wwqw")
}

2. 三目運(yùn)算符

a == 1 ? print("first") : print("hello")

3. guard

  1. guard條件成立闹丐,繼續(xù)往下走,不成立執(zhí)行else里面的語句
  2. else后要跳出語句被因,配合return,continue,break,throw等使用
func funcTest() {
    let a = 1
    guard a == 1 else {
        print("a != 1")
        return
    }
    print("a == 1")
    
}

4. switch的用法

1. switch與基本數(shù)據(jù)

// 必須要加default, 但是有些情況可以不加卿拴,例如枚舉的各個情況都判斷過了
// 判斷類型 可以是浮點(diǎn)型,String梨与,對象堕花。
let a = 11

switch a {
case 1, 11:
    print("1, 11")
    fallthrough // 會有穿透效果粥鞋,如果這個case為true,也執(zhí)行下個case的內(nèi)容
case 2:
    print("2")
default:
    print("不知道")
}

2. switch與區(qū)間

let score = 10.0
switch score {
case 0 ..< 60:
    print("不及格")
case 60 ..< 90:
    print("及格")
case 90 ..< 100:
    print("優(yōu)秀")
default:
    print("default")
}

3. switch與枚舉

enum Direction {
    case up
    case down
    case left
    case right
}

let rr = Direction.right
switch rr {
case Direction.up:
    print("up")
case Direction.down:
    print("down")
case Direction.left:
    print("right")
case Direction.right:
    print("right")
//default: // 此時可以省略default缘挽,因為各個情況都已經(jīng)判斷過,default也不會執(zhí)行
//    print("ss")
}

4. switch與元組

let point = (10, 25)
switch point {
case (0, 0):
    print("坐標(biāo)在原點(diǎn)")
case (1...10, 10...20): // 可以在元組中再加上區(qū)間
    print("坐標(biāo)的X和Y在1~10之間")
case (_, 0): // X可以是任意數(shù)
    print("坐標(biāo)的X在X軸上")
case (var x, var y): // x,y來接收參數(shù) 一定為true
    print("333")
case var(x,y): where x > y // x,y來接收參數(shù) x>y則一定為true
    print("1111")
default:
    print("Other")
}

循環(huán)

1. for循環(huán)

for i in 0 ..< 10 {
    print(i)
}

// _代表忽略的意思
for _ in 0 ..< 10 {
    print("test")
}

2. while循環(huán)

1. while循環(huán)

var i = 10
while i > 0 {
    i -= 1
    print(i)
}

2. repeat~while循環(huán)

// do 特殊含義,捕捉異常
repeat {
    i += 1
    print(i)
} while i < 10

字符串處理

let str2 = "123"
let int4 = 10

// 字符串拼接
str2 + "\(int4)"

// 遍歷字符串
for i in str2.characters {
    print(i)
}

str2.lengthOfBytes(using: String.Encoding.utf8)
str2.characters.count
String(format: "%02d", 1)

// 截取字符串
str2.substring(from: str2.startIndex)
str2.substring(to: str2.index(after: str2.startIndex))
str2.substring(from: str2.index(str2.startIndex, offsetBy: 2))
str2.substring(from: str2.index(str2.endIndex, offsetBy: -1))
let range = str2.startIndex ..< str2.endIndex
str2.substring(with: range)
str2.replaceSubrange(range, with: "sss")

// 轉(zhuǎn)為OC的NSString處理
let str3 = (str2 as NSString).substring(to: 2)

數(shù)組

// 數(shù)組的聲明和初始化
let arr1 = [2]
var arr2 : [Any] = [1, 2, "ii", 11, "ss", "w"]
let arr3 = [1, 1.1, "ss"] as [Any]

// 相同類型的數(shù)組可以直接相加
arr2 + arr3

// 獲取
arr2.first
arr2.last
arr2[0]
// 追加
arr2.append(2.0)
// 修改
arr2[0] = 1
// 插入
arr2.insert("sww", at: 2)
// 刪除
arr2.remove(at: 0)
arr2.removeFirst()
arr2.removeFirst(1)

// 操作數(shù)組的區(qū)間
let rang2 = 0 ..< 2
arr2.removeSubrange(0 ..< 2)

// 獲取數(shù)組最大最小
var arr = [1, 2]
arr.min()
arr.max()
var arr4 = ["a", "3.3"]
// 比的ASCII碼
arr4.min()
arr4.max()

// 數(shù)組的遍歷
for i in 0 ..< arr2.count {
    print(arr2[i])
}

// 利用元組獲取數(shù)組的 角標(biāo)+ 值
for (key ,value) in arr2.enumerated() {
    print(key, value)
}

for i in arr2[0...2] {
    print(i)
}

// 轉(zhuǎn)為OC數(shù)組的遍歷
(arr2 as NSArray).enumerateObjects({ (value, idx, stop) in
    print(value, idx)
}) 

字典

var dict : [String : Any] = ["key" : 1, "key2" : "value"]
dict["key"] = 2

let index = dict.index(forKey: "key")
// index為nil報錯
dict.remove(at: index!)

// 有則改壕曼,無則加
dict.updateValue("value2", forKey: "key2")
dict.removeValue(forKey: "key2")
dict.removeAll()


for value in dict.values {
    print(value)
}

for (key ,value) in dict {
    print(key, value)
}

// 類擴(kuò)展---字典的相+
extension Dictionary {
    static func +(dic : Dictionary, dic2 : Dictionary) -> Dictionary
    {
        var result = dic
        for (key , value) in dic2 {
            result[key] = value
        }
        return result
    }
}

元組

// 元組類型 (name: String, Int, score: Int)苏研, 可以作為返回值
let yz = (name : "zhangsan", _ : 18, score : 2)
yz.0
yz.name
yz.score

let(name, age, score) = ("zhangsan", 2, 2)

可選類型

1. 非可選類型 (使用的時候必須有值)

let sum : Int

2. 可選類型 (才能賦值為nil)

Swift中的nil != OC中的nil,Swift種的nil就是一個特殊含義的字符窝稿,表示沒有值

// let sum0 : Int?  
// let sum0 : Optional<Int> = 2

let sum1 : Int!
sum = nil

// sum0 (Int?)需要解包才能使用
// sum1 (Int!)賦值后可以直接使用楣富,不用解包

3. 四種方式使用可選類型的值

1. 判斷 + 直接解包

if sum != nil {
    sum!
}

2. 可選綁定

if let tmp = sum {
    tmp
}

3. guard守護(hù)

func funcl(tmp : Int?) {
    guard let test = tmp else {
        return
    }
    test
}

4. 空合運(yùn)算符

// 如果sum == nil,那么取 ?伴榔? 后面的值
// 如果 sum != nil, 取 sum! 強(qiáng)制解包后的值 
let tmp2 = sum ?? 0

類型轉(zhuǎn)換

var a = 8.8
a is Int
a is Double


let str = "123"
str as NSString
str as Any

// as! 代表纹蝴,肯定可以轉(zhuǎn)換成功,轉(zhuǎn)換的結(jié)果踪少,是非可選 不能為nil
// as? 代表塘安,系統(tǒng)嘗試幫你進(jìn)行轉(zhuǎn)換,轉(zhuǎn)失敗了援奢,就為nil

函數(shù)

1. 函數(shù)的四種類型

1. 無參數(shù)兼犯,無返回值

func func1() {
    
}
func func2() -> Void {
    
}
func func3() -> () {
    
}

2. 無參數(shù),有返回值

func func1() {
    
}
func func2() -> Int {
    return 0
    
}
// 返回元組
func func3() -> (Int, String) {
    return (1, "123")
}

3. 有參數(shù)集漾,無返回值

func func1(age : Int) {
    
}

4. 有參數(shù)切黔,有返回值

func func3(age : Int) -> (Int, String) {
    return (1, "123")
}

函數(shù)其他注意

1. 省略第一個外部參數(shù)的名字

// 省略第一個內(nèi)部參數(shù)(函數(shù)內(nèi)部可以使用的參數(shù))
// 從swift3.0開始默認(rèn)第一個參數(shù)既是外部參數(shù)(函數(shù)調(diào)用時可以看到的參數(shù))也是內(nèi)部參數(shù)
func func2(_ name : Int, name2 : Int) -> Int {
    return 0
}

2. 設(shè)置參數(shù)默認(rèn)值

// 設(shè)置默認(rèn)值,會生成幾種組合(帶不帶第二個參數(shù)的)
func func2(name : Int, name2 : Int = 1) -> Int {
    return 0
}

3. 設(shè)置可變參數(shù)

 // 可變參數(shù)  類型...
 // 函數(shù)內(nèi)部具篇,把這個參數(shù)纬霞,當(dāng)做數(shù)組來處理
 // 函數(shù)外部,直接可以傳遞多個值驱显,用逗號隔開
func addNum(nums : Int...) -> Int {
    var result = 0
    for num in nums {
        result += num
    }
    return result
}
addNum(nums: 1, 2, 3)

4. 修改內(nèi)部參數(shù)的值

// 默認(rèn)不能修改內(nèi)部參數(shù)的值
func change(num : Int) {
    // num 為常亮诗芜,不能修改
    var num = num
    num = 3
}
let a = 0
change(num: a)

5. 設(shè)置參數(shù)為地址傳遞

 // inout設(shè)置第一個參數(shù)為地址傳遞
func func1(name : inout Int, name2 : Int) -> Int {
    return 0
}

6. 函數(shù)嵌套

func test() {
    func test2() {
        print("sss")
    }
}

7. 函數(shù)的類型

// (Int, Int) -> Int
// 函數(shù)的類型 : 參數(shù)類型 和返回值類型
func add(num : Int, num2 : Int)  -> Int{
    return num + num2
}

// (Int, Int) -> Int
// 函數(shù)的類型 : 參數(shù)類型 和返回值類型
func jian(num : Int, num2 : Int)  -> Int{
    return num - num2
}


func exec(n1 : Int, n2 : Int, fun : (Int, Int) -> Int) {
    let result = fun(n1 ,n2)
    print(result)
}

exec(n1: 3, n2: 2, fun: add)
exec(n1: 3, n2: 2, fun: jian)

8. 區(qū)分不同函數(shù)

func test() {   
}
// 參數(shù)返回值不同
func test() -> Int {
    return 0
}
// 參數(shù)類型不同
func test(age : Int) -> Int {
    return 0
}
// 參數(shù)名字不同
func test(_ age : Int) -> Int {
    return 0
}
// 參數(shù)名字不同
func test(name : Int) -> Int {
    return 0
}

枚舉

// 在swift里面,枚舉類型埃疫,默認(rèn)情況伏恐,不表示任何類型,就是一個標(biāo)識
// 類型首字母大寫栓霜,元素小寫
enum Direction {
    case east
    case west
}

enum Direction2 {
    case east, west
}

enum Direction3 : Int {
    case east = 1
    case west = 3
    case north // Direction3.north.rawValue = 4 會自己累加
    case south
}

// 只有后邊指定類型才能敲出rawValue
// Direction4.left.rawValue 取出的值就是指定的類型
enum Direction4 : String {
    case left = "left"
    case right = "right"
    case top
    case down
    
    func func1() {
        print("wwwww")
    }

    static func func2() {
        print("rrrr")
    }
}

let rv = Direction3.north.rawValue
let rv2 = Direction3(rawValue: 1)
let rv3 = Direction4(rawValue: "left")

func test(path : Direction4) {
    if path == .left {
        print(path.rawValue)
    }
}

結(jié)構(gòu)體

1. 結(jié)構(gòu)體基本使用

// 類型方法 static func
// 實(shí)例方法 func
// 無論是枚舉翠桦,還是結(jié)構(gòu)體,都可以寫方法
struct Point {
    // 實(shí)例屬性
    var x : Double
    var y : Double
    // 實(shí)例方法
    func distance() -> Double {
        return x - y
    }

    mutating func distance2() -> Double {
        x += 2  // 修改實(shí)例屬性 方法要加mutating
        print(Point.z) // 訪問類型屬性
        return x - y
    }
    
    // 類型屬性
    static var z : Double = 0 // 需要初始化
    // 類型方法
    static func dis() {
//        print(x) 不能直接訪問x
        print(z)
        print(Point.z)
    }
    
}

2. 結(jié)構(gòu)體擴(kuò)充構(gòu)造函數(shù)

struct Point {
    // 實(shí)例屬性
    var x : Double
    var y : Double
    var z : Double?
    
    // 自定義 “構(gòu)造函數(shù)” 叙淌!= 普通函數(shù)
    // 不加func,必須使用init作為名稱
    // 在構(gòu)造函數(shù)內(nèi)部秤掌,必須要保證,所有的非可選屬性鹰霍,必須有值
    // 如果我們自定義了構(gòu)造函數(shù)闻鉴,那么系統(tǒng)生成的逐一構(gòu)造器,就沒有了
    init(x : Double, y : Double) {
        self.x = x
        self.y = y
    }
    init(x : Double, y : Double, z : Double) {
        self.x = x
        self.y = y
        self.z = z
    }
    
}

1. 類的聲明初始化

// swift類茂洒,是可以不繼承父類孟岛,那它本身就是rootClass
// 可以寫屬性和方法
// 屬性:實(shí)例屬性,類型屬性
// 方法:實(shí)例方法,類型方法
// 類渠羞,默認(rèn)情況下斤贰,不會生成逐一構(gòu)造器(目的,保證所有的非可選屬性有值)
// 默認(rèn)情況下次询,不能保證荧恍,所有的非可選屬性有值
// 一個實(shí)例對象被創(chuàng)建好以后,必須保證里面所有的非可選屬性有值
// 方案1:在構(gòu)造函數(shù)中入手屯吊,給非可選屬性初始化
// 方案2:把非可選 -> 可選
// 方案3:給非可選的屬性賦值默認(rèn)值

class Person {
    var age : Int
    init(age : Int) {
    // 為了不與age參數(shù)沖突才使用self
        self.age = age
    }
    init() {
        age = 2
    }
}
// 不會生成逐一構(gòu)造器
let p = Person()
let p2 = Person(age: 3)

2. 類的屬性和方法

class Person {
    // 實(shí)例屬性 - 存儲屬性(可以用來存儲數(shù)值的屬性)
    var score = 1
    var score2 : Int = 0  {
        willSet {
            score2 // old
            newValue // new
        }
        
        //        willSet(changeName) {
        //            score2 // old
        //            changeName // new
        //        }
        didSet {
            score2 // new
            oldValue // old
        }
    }
    // 實(shí)例屬性 - 計算屬性(并不是直接用來存儲數(shù)值的送巡,它是通過某些計算得來的數(shù)值)
    var b : Int {
        get {
            return score + score2
        }
        set {
            newValue
        }
    }
    // 類型屬性
    static var c = 1
    static var d : Int?
    // 實(shí)例方法
    func func1() {
        self.score += 1
    }
    
    // 類型方法 - 不可以被子類重寫override
    static func func2() {
        print("rrrr", c)
    }
    // 類型方法 - 可以被子類重寫(結(jié)構(gòu)體不能用class聲明方法)
    class func func3() {
        print("sss")
    }
    // 結(jié)構(gòu)體不能使用deinit析構(gòu)函數(shù)
    // 析構(gòu)函數(shù)只能被定義在class類中,不能在extension中
    deinit {
        print("類死了")
    }
}

3. 類的繼承之KVC使用

class Person : NSObject {

    var age : Int = 0
    var name : String = ""

    init(dic : [String : Any]) {
        
        // KVC實(shí)現(xiàn)之前盒卸,必須調(diào)用父類的init方法初始化
        super.init()
        setValuesForKeys(dic)
    }
}

let dic : [String : Any] = ["name" : "zhangsan", "age" : 33]
let stu = Person(dic: dic)

4. 類的循環(huán)引用

class Person {
    var dog : Dog?
    deinit {
        print("人掛了")
    }
}
class Dog {
    // 使用weak來避免循環(huán)引用 (unowned也可以)
    weak var master : Person?
    deinit {
        print("??掛了")
    }
}

var p : Person? = Person()
var d : Dog? = Dog()
p?.dog = d
d?.master = p

p = nil
d = nil

5. 結(jié)構(gòu)體和類的區(qū)別

  1. 結(jié)構(gòu)體有逐一構(gòu)造器骗爆,類沒有
  2. 結(jié)構(gòu)體是值類型,類是引用類型
  3. 結(jié)構(gòu)體不能繼承(意味著沒有多態(tài))

6. OC中使用Swift的類和結(jié)構(gòu)體

  1. OC與Swift混編蔽介,Swift中的函數(shù)名要符合OC的規(guī)范摘投,重載的方法用@objc指定名字,避免沖突
  2. 如果是類虹蓄,必須要繼承自NSObject犀呼,而且用public關(guān)鍵字對類、方法薇组、屬性等進(jìn)行修飾
  3. 如果是協(xié)議最好繼承自NSObjectProtocol(也就對應(yīng)OC中的基協(xié)議)圆凰,用標(biāo)識符@objc,而且聲明為public
  4. Build Settings搜索-Swift体箕,找到 Objective-C Generated Interface Header Name 里面的.h文件即為OC調(diào)用時,要包含的頭文件 #import "XXX-Swift.h"
public class Person : NSObject {
    public var name : String = ""
    public func getAge() {
        print("hello age")
    }
}

@objc
public protocol work : NSObjectProtocol{
    func goWork()
}

7. Swift中調(diào)用OC

  1. Swift項目創(chuàng)建OC文件時回生成.h橋接文件挑童,可以在Build SettingsObjective-C Bridging Header中找到累铅,也可以自己創(chuàng)建.h文件,路徑跟系統(tǒng)生成的一致
  2. 在.h文件包含對應(yīng)的OC頭文件

三大特性

類的三大特性:封裝站叼、繼承娃兽、多態(tài)

 class Test : NSObject {
    // 類繼承NSObject后,下面兩個方法會報錯尽楔,說是轉(zhuǎn)換到OC以后兩個方法有沖突
    func chongzai(a : Int) {
    }
    
    func chongzai(a : Double) {  
    }
}

解決辦法:

public class Test : NSObject {
    public func chongzai(a : Int) {    
    }
    
    // 通過此標(biāo)識投储,自定義生成的方法名,解決重復(fù)沖突
    @objc(chongzai:)
    public func chongzai(a : Double) {
        
    }
}
// 項目名稱為app阔馋,彈框選擇的是不橋接
// Build Settings搜索-Swift玛荞,找到 Objective-C Generated Interface Header Name 里面的.h文件即為要包含的頭文件
#import "app-Swift.h"
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    Test *t = [[Test alloc] init];
    [t chongzaiWithA:(NSInteger)];
}

可選鏈

class Person {
    var dog : Dog?
}

class Dog {
    var name : String = "wangcai"
    var toy : Toy?
}

class Toy {
    var price : Double = 0.0
}
let p = Person()
// 如果可選鏈的結(jié)果是nil,就代表鏈條中間至少有一個環(huán)節(jié)斷了
// () == Void != nil
p.dog?.toy?.price

協(xié)議

1.協(xié)議的基本使用

protocol work {
    func run()
}
// 枚舉也可以遵循協(xié)議
enum Direction : work {
    case left
    case right
    
    // 實(shí)例方法
    func run() {
        print("Direction run")
    }
}
Direction.left.run()

// 協(xié)議可以繼承呕寝,這里不叫遵循勋眯,遵循work協(xié)議是要實(shí)現(xiàn)函數(shù)的
protocol work2 : NSObjectProtocol{
    func run2()
}
// 如果遵循了協(xié)議,要求,必須實(shí)現(xiàn)協(xié)議里的所有方法
// 同時繼承 + 遵循協(xié)議客蹋,不支持多繼承
// NSObject 實(shí)現(xiàn)了NSObjectProtocol協(xié)議的所有方法
class Stu : NSObject, work2 {
    func run2() {
        print("Stu run2")
    }
}

2. 協(xié)議中使用代理

  1. weak 修飾類塞蹭,work : class,輕量級
  2. work : NSObjectProtocol也可以,但是遵循work協(xié)議的類讶坯,都要繼承要NSObject
protocol work : NSObjectProtocol{
    func run()
}
//protocol work : class{
//    func run()
//}

class Stu {
    weak var delegate : work?
    func run() {
        print("Stu run2")
    }
}

3. 協(xié)議中的可選

協(xié)議中的可選番电,僅僅是OC的特性,Swift是不支持的
解決方案:就是讓Swift協(xié)議辆琅,擁有OC特性

@objc
protocol work {
  @objc optional  func run()
}

class Stu : work {
    func run() {
        print("Stu run2")
    }
}

泛型

// 泛化的類型漱办,不是某一個具體的類型, <T>中的T可以自定義名字
func exchange<T>(num1 : inout T, num2 : inout T) {
    let tmp = num1
    num1 = num2
    num2 = tmp
}

class Person {  
}

// 限制 T 必須繼承自 Person
func exchange2<T>(num1 : inout T, num2 : inout T) -> Int  where T : Person  {
    let tmp = num1
    num1 = num2
    num2 = tmp
    return 0
}

var a = 3
var b = 9
var p1 = Person()
var p2 = Person()
exchange(num1: &a, num2: &b)

// 參數(shù)必須繼承自 Person
exchange2(num1: &p1, num2: &p2)

閉包

閉包 == 特殊的函數(shù)

1.閉包的基本使用

// 函數(shù)
func add(num1 : Int, num2 : Int) -> Int {
    return num1 + num2
}

// 簡單的閉包
// 如果閉包,參數(shù)是沒有的涎跨,可以省略洼冻,in和in前面的內(nèi)容
var bibao : ()->() = {
    //    ()->() in // 可以省略
}
// 帶參數(shù)的閉包
var bibao2 : (Int, Int)->(Int) = {
//    (varg1, varg2) in
    (varg1 : Int, varg2 : Int) in
    return varg1 + varg2
}

bibao2(10, 20)

// 閉包當(dāng)做參數(shù)
func exec(n1 : Int, n2 : Int, block : (Int, Int)->(Int)) -> Int {
    return block(n1, n2)
}
exec(n1: 20, n2: 30, block: add)
exec(n1: 20, n2: 30, block: bibao2)
exec(n1: 20, n2: 30, block: {
    (a : Int, b : Int)->(Int) in
    return a * b
})

2. 尾隨閉包和逃逸閉包

//尾隨閉包是一個書寫在函數(shù)括號之后的閉包表達(dá)式,函數(shù)支持將其作為最后一個參數(shù)調(diào)用隅很。在使用尾隨閉包時撞牢,你不用寫出它的參數(shù)標(biāo)簽(此處是bb)
// 如果一個函數(shù)的參數(shù),是一個閉包類型叔营,那么默認(rèn)情況下屋彪,是一個“非逃逸”閉包;(閉包绒尊,生命周期畜挥,是函數(shù))
func test(a : Int, bb : (Int, Int)->(Int)) {
    let result = bb(a, 3)
    print(result)
}

test(a: 20) { (sum1, sum2) -> (Int) in
    return sum1 - sum2
}

// @escaping : 代表,這個閉包婴谱,是逃逸閉包蟹但,以后,有可能谭羔,會被其他的閉包华糖,延長生命周期(強(qiáng)引用)
func test2(bb : @escaping (Int, Int)->(Int)) {
    bb(23, 3)
    let queue = DispatchQueue(label: "xx")
    let time = DispatchTime.now() + DispatchTimeInterval.seconds(2)
    queue.asyncAfter(deadline: time) { 
        // 此處編譯器會提示添加 @escaping
        _ = bb(10, 3)
    }
}
test2 { (sum, sum2) -> (Int) in
    return sum * sum2
}

3. 閉包的循環(huán)引用(4中解決方式)

class Person {
class Person {
    var resultBlock : (()->())?
    var age : Int = 0
    func test() {
        // weak 對象最后會被置為 nil,所以var
        weak var weakSelf = self
        resultBlock = {
            print("222",weakSelf?.age)
        }
        resultBlock?()
    }
    func test2() {
        resultBlock = {
            [weak self] in
            print(self?.age)
        }
        resultBlock?()
    }
    
    func test3() {
        // unowned == __unsafe_unretained 最后不會置為nil瘟裸,編譯器建議為let
        unowned let weakSelf = self
        resultBlock = {
            print(weakSelf.age)
        }
        resultBlock?()
    }

    
    func test4() {
        resultBlock = {
            [unowned self] in
            print(self.age)
        }
        resultBlock?()
    }
    deinit {
        print("人被釋放了")
    }
}
var p : Person? = Person()
p?.test()
p = nil

懶加載

只是在第一次訪問的時候客叉,會調(diào)用相應(yīng)的函數(shù),獲取實(shí)例话告,下次即使值為nil兼搏,也不會再次調(diào)用相應(yīng)的函數(shù),獲取新的實(shí)例

class Dog {
    var name : String = "wangcai"
    init() {
        print("創(chuàng)建了小狗")
    }
}

// 懶加載
// 函數(shù):構(gòu)造函數(shù)沙郭,一般的函數(shù)佛呻,閉包
// = 后面可以跟的值:具體的指,構(gòu)造“函數(shù)”
// 所謂的懶加載病线,是指件相,在用的時候再扭,再通過后面的函數(shù),獲取相應(yīng)的實(shí)例
class Person {
    lazy var dog : Dog = Dog()
    // 這樣的懶加載可以對創(chuàng)建的對象進(jìn)行修改
    lazy var dog2 : Dog = Person.getDog()
    // 懶加載內(nèi)容放到閉包夜矗,最后調(diào)用閉包
    lazy var dog3 : Dog = {
        let d = Dog()
        d.name = "dog3"
        return d
    }()
    lazy var dog4 : Dog = {
        $0.name = "dog4"
        return $0
    }(Dog())
    
    
    static func getDog() -> Dog {
        let d = Dog()
        d.name = "getDog"
        return d
    }
}

注釋

// MARK: - ARC
// TODO: - todo
// FIXME: 解決bug

訪問權(quán)限

  1. Swift中的訪問控制模型基于模塊和源文件泛范、類這三個概念
  2. Swift訪問權(quán)限,作用于類紊撕,屬性罢荡,方法等
  3. Swift中的訪問級別遵循一個基本原則:不可以在某個實(shí)體中定義訪問級別更高的實(shí)體(類如果都不能訪問,里面的屬性方法就算開放了也不能訪問)

訪問修飾符

  1. internal : 在本模塊中都可以訪問对扶,(默認(rèn))区赵,子類也可以繼承
  2. private : 當(dāng)前類私有
  3. fileprivate : 在當(dāng)前源文件中可以訪問
  4. public : 跨模塊時,如果修飾類浪南,則無法繼承笼才。修飾方法,不能被override
  5. open : 跨模塊時络凿,如果修飾類骡送,可以繼承。修飾方法絮记,可以被override

方法拋出異常

// Error 就是在告訴編譯器摔踱,這個枚舉,可以充當(dāng)具體的異常值
enum FileError : Error{
    case notExists
    case notFormat
    case notContent
}

// path 不存在 nil
// path存在怨愤,但是派敷,路徑對應(yīng)的文件格式不對 .png
func readFile(path : String) throws -> String {
    // 1. 判斷文件路徑是否存在
    let isExists = FileManager.default.fileExists(atPath: path)
    if !isExists {
        // 在這里面,拋出撰洗,出現(xiàn)問題的原因
        // 如果想要成為篮愉,異常值,必須要遵循一個協(xié)議Error
        throw FileError.notExists
//        return
    }
    
    // 2. 讀取文件內(nèi)容
    // 判定差导,如果這個構(gòu)造函數(shù)潜支,出現(xiàn)了異常,一般都是格式不正確
    var content : String = ""
    do {
        content = try String(contentsOfFile: path)
    } catch  {
        // 捕捉到異常柿汛,會執(zhí)行這個閉包
        throw FileError.notFormat
    }
    if content.lengthOfBytes(using: String.Encoding.utf8) == 0 {
        throw FileError.notContent
    }
    return content
}

Playground

1. Playground異步執(zhí)行

// Playground中的代碼會從上到下執(zhí)行,并在執(zhí)行完畢之后立即停止埠对,如果想要測試異步處理(比如網(wǎng)絡(luò)請求)
// 1. 導(dǎo)入PlaygroundSupport
// import PlaygroundSupport
// 2. 讓Playground永遠(yuǎn)執(zhí)行
//PlaygroundPage.current.needsIndefiniteExecution = true
// 3. 停止執(zhí)行
// PlaygroundPage.current.finishExecution()

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let queue = DispatchQueue(label: "xx")
let time = DispatchTime.now() + DispatchTimeInterval.seconds(2)
queue.asyncAfter(deadline: time) {
    print("finish")
    PlaygroundPage.current.finishExecution()
}
print("first")

2. MarkDown語法

從Xcode右邊文件屬性络断,選中Render Documentation看渲染效果

//: [Previous](@previous) 
//: [Next](@next)

//PageName為頁名字不能有空格
//: [Go to AnyPage](PageName)

3. TimeLine使用

點(diǎn)擊右上角雙環(huán)(Show the Assistant editor),在代碼中做的動畫可以在TimeLine中預(yù)覽

4. Playground的Sources目錄

  1. 放到Sources目錄下的源文件會被編譯成模塊(module)并自動導(dǎo)入到Playground中,只會編譯一次
  2. 使用注意:需要使用public關(guān)鍵字修飾資源文建中项玛,需要暴露給外界的內(nèi)容
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末貌笨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子襟沮,更是在濱河造成了極大的恐慌锥惋,老刑警劉巖昌腰,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異膀跌,居然都是意外死亡遭商,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門捅伤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來劫流,“玉大人,你說我怎么就攤上這事丛忆§艋悖” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵熄诡,是天一觀的道長可很。 經(jīng)常有香客問我,道長凰浮,這世上最難降的妖魔是什么我抠? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮导坟,結(jié)果婚禮上屿良,老公的妹妹穿的比我還像新娘。我一直安慰自己惫周,他們只是感情好尘惧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著递递,像睡著了一般喷橙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上登舞,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天贰逾,我揣著相機(jī)與錄音,去河邊找鬼菠秒。 笑死疙剑,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的践叠。 我是一名探鬼主播言缤,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼禁灼!你這毒婦竟也來了管挟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤弄捕,失蹤者是張志新(化名)和其女友劉穎僻孝,沒想到半個月后导帝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡穿铆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年您单,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悴务。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡睹限,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出讯檐,到底是詐尸還是另有隱情羡疗,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布别洪,位于F島的核電站叨恨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏挖垛。R本人自食惡果不足惜痒钝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望痢毒。 院中可真熱鬧送矩,春花似錦、人聲如沸哪替。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凭舶。三九已至晌块,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間帅霜,已是汗流浹背匆背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留身冀,地道東北人钝尸。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像搂根,于是被迫代替她去往敵國和親珍促。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,776評論 1 10
  • Swift 介紹 簡介 Swift 語言由蘋果公司在 2014 年推出兄墅,用來撰寫 OS X 和 iOS 應(yīng)用程序 ...
    大L君閱讀 3,176評論 3 25
  • 136.泛型 泛型代碼讓你可以寫出靈活,可重用的函數(shù)和類型,它們可以使用任何類型,受你定義的需求的約束。你可以寫出...
    無灃閱讀 1,452評論 0 4
  • 擴(kuò)展 擴(kuò)展就是向一個已有的類澳叉、結(jié)構(gòu)體隙咸、枚舉類型或者協(xié)議類型添加新功能沐悦。這包括在沒有權(quán)限獲取原始源代碼的情況下擴(kuò)展類...
    cht005288閱讀 460評論 0 0
  • 常量與變量使用let來聲明常量,使用var來聲明變量五督。聲明的同時賦值的話藏否,編譯器會自動推斷類型。值永遠(yuǎn)不會被隱式轉(zhuǎn)...
    莫_名閱讀 436評論 0 1