Swift基礎(chǔ)語法

簡介

  • 特點
    (1)優(yōu)于OC,快速,安全
    (2)取消了預(yù)編譯指令包括宏定義(OC用的太多了)
    (3)取消了OC指針和不安全訪問的使用(看不到星星了)
    (4)舍棄 Objective-C 早期應(yīng)用 Smalltalk 的語法,全面改為點語法
    (5)3.0中對Foundation框架做了很多改變,去除了NS疼约,將絕大部分class轉(zhuǎn)換成struct結(jié)構(gòu)體(為了考慮性能和安全性,絕大部分使用結(jié)構(gòu)體來代替以前的類蝙泼,但是在實際使用感覺不到)
    (6)可以使用現(xiàn)有的 Cocoa 和 Cocoa Touch 框架
    , 以前是OC調(diào)UIKit程剥,現(xiàn)在就是Swift調(diào)UIKit,這點事沒問題的
    (7)Swift因為語法的嚴(yán)謹(jǐn)性可以讓很多錯誤提前遇到汤踏,這樣很少出現(xiàn)bug讓程序停在main導(dǎo)致無法找到
    (8)@UIApplicationMain是程序的入口
    (9)只有.h沒有.m
    (10)所有的代碼都包括在{}里织鲸,默認(rèn)方法func都有縮進(jìn)!
    (11)語法的allocinit替換成()

  • PlayGround
    (1)可以看蘋果官方自帶的tips和100個tips溪胶,都在Placground來使用

  • 基礎(chǔ)點
    (1)不適用self. 在閉包或者編譯器提示的時候再使用
    (2)分號是用來分割語句的搂擦,如果一行洗很多,就可以加分號哗脖,一般時候可以不加
    (3)#function打印執(zhí)行的函數(shù)
    (4)添加標(biāo)記用到// MARK: - 選擇瀑踢,如果是接下來要做的可以用// TODO:和// FIXME:這些非常有用

一、常量和變量

定義

  • let 定義常量才避,一經(jīng)賦值不允許再修改

  • var 定義變量橱夭,賦值之后仍然可以修改
    常量和變量的細(xì)節(jié)

    • 使用 : 類型,僅僅只定義類型
    • 常量有一次設(shè)置的機(jī)會
    • 應(yīng)該盡量先選擇常量桑逝,只有在必須修改時徘钥,才需要修改為 var
// 定義常量并且直接設(shè)置數(shù)值
let x: Int = 10
// 常量數(shù)值一經(jīng)設(shè)置,不能修改肢娘,以下代碼會報錯
// x = 30

let y: Int
// 常量有一次設(shè)置的機(jī)會呈础,以下代碼沒有問題,因為 `y` 還沒有被設(shè)置數(shù)值
y = 10

// 一旦設(shè)置之后橱健,則不能再次修改而钞,以下代碼會報錯,因為 `y` 已經(jīng)被設(shè)置了數(shù)值
// y = 50

print(x + y)

// 變量設(shè)置數(shù)值之后拘荡,可以繼續(xù)修改數(shù)值
var z: Int
z = 100
z = 200

print(x + y + z)

自動推導(dǎo)

Swift 能夠根據(jù)右邊的代碼臼节,推導(dǎo)出變量的準(zhǔn)確類型
只有相同類型的值才能夠進(jìn)行運算

// 整數(shù)默認(rèn)的類型是 Int
let intValue = 200
// 小數(shù)的默認(rèn)類型是 Double
let doubleValue = 10.5

// 如果要對不同類型的數(shù)據(jù)進(jìn)行計算,必須要顯式的轉(zhuǎn)換
print(intValue + Int(doubleValue))
print(Double(intValue) + doubleValue)

注意:Swift對類型要求異常嚴(yán)格,任何不同類型的數(shù)據(jù)不能直接運算(哪怕是Int和Double)网缝,不會做一些自動的轉(zhuǎn)換來轉(zhuǎn)換成Double巨税。Swift不存在基本數(shù)據(jù)類型,Int和Double都是結(jié)構(gòu)體其實粉臊,強(qiáng)轉(zhuǎn)用Double(x)完成草添,或者在定義的時候直接指定變量的類型let x : Double = 10;(很少使用)

二、控制流

if

  • Swift 中沒有 C 語言中的非零即真概念
  • 在邏輯判斷時必須顯示地指明具體的判斷條件 true / false
  • if 語句條件的 () 可以省略
  • 但是 {} 不能省略
let num = 100

if num > 10 {
    print("大 \(num)")
} else {
    print("小 \(num)")
}

三目

  • Swift 中的 三目 運算保持了和 OC 一致的風(fēng)格
  • 提示:以下代碼扼仲,可以按 cmd + shift + y远寸,打開控制臺,查看輸出結(jié)果
num > 10 ? print("大 \(num)") : print("小 \(num)")

或者

num > 10 ? print("大 \(num)")  : () 
這樣就對后面的不作處理屠凶。
() 表示空執(zhí)行驰后。

switch

  • switch 不再局限于整數(shù)
  • switch 可以針對任意數(shù)據(jù)類型進(jìn)行判斷
  • 每一個 case 后面必須有可以執(zhí)行的語句
  • 不再強(qiáng)制需要 break
  • 如果沒有任何需要執(zhí)行的語句,可以使用 break
    要保證處理所有可能的情況矗愧,不然編譯器直接報錯灶芝,不處理的條件可以放在 default 分支中
  • 每一個 case 中定義的變量僅在當(dāng)前 case 中有效,而 OC 中需要使用 {}
  • 多值 case 可以使用 , 分隔
let scoreString = "優(yōu)"

switch scoreString {
case "優(yōu)":
    let name = "學(xué)生"
    print(name + "80~100分")
case "良", "中": print("60~80分")
case "差": print("不及格")
default: break
}

switch 的條件判斷

  • switch 中可以使用 where 子句判斷條件
  • 如果只做條件判斷唉韭,case 部分可以使用 _ 省略
  • 提示:Swift 中可以使用 _ 忽略任何不關(guān)心的內(nèi)容
let score = 90
switch score {
case _ where score >= 80: print("優(yōu)")
case _ where score >= 70: print("良")
case _ where score >= 60: print("中")
default: print("差")
}

for

  • swift取消了i++和++i和傳統(tǒng)的for循環(huán)
for i in 0...5 {

}

for i in 0..<5 {

}
  • 反序遍歷
 for i in (0..<10).reversed() {
        
}

三夜涕、可選項(Optional)

簡要

(1)定義變量時,如果是可選的纽哥,表示可以有值钠乏,也可以是nil栖秕,用“春塌?”
(2)強(qiáng)行解包 “!”簇捍,程序員來注意只壳!,并且要少用暑塑,可能會崩
(3)最常見的錯誤:解包的時候發(fā)現(xiàn)nil吼句。fatal error: unexpectedly found nil while unwrapping an Optional value
(4)let可選的話,沒有默認(rèn)值事格,需要賦值惕艳。var可選的話,默認(rèn)值為nil
(5)可選項在參與計算時候必須解包

概念

  • Optional 是 Swift 的一大特色驹愚,也是 Swift 初學(xué)者最容易困惑的問題
  • 定義變量時远搪,在類型后面添加一個 ?,表示該變量是可選的
  • 定義變量時逢捺,如果指定是可選的谁鳍,表示該變量:
    • 可以有一個指定類型的值
    • 也可以是 nil

定義

  • 格式1(自動推導(dǎo)):var 變量名: Optional = 值
  • 格式2(泛型):var 變量名:Optional<類型> = 值
  • 格式3(簡化格式):var 變量名: 類型? = 值
// 格式1
let x: Optional = 20
// 格式2
let y: Optional<Int> = 30
// 格式3
let z: Int? = 10

print(x)
print(y)
print(z)

默認(rèn)值

  • 變量可選項的默認(rèn)值是 nil
  • 常量可選項沒有默認(rèn)值,需要在定義時,或者構(gòu)造函數(shù)中賦值
var x1: Int?
print(x1)

let x2: Int?
// 常量可選項沒有默認(rèn)值倘潜,在賦值之前不能使用
// print(x2)
x2 = 100
print(x2)

計算和強(qiáng)行解包

  • 可選值在參與計算前绷柒,必須解包 unwarping
  • 只有解包(unwrap)后才能參與計算
  • 在可選項后添加一個 !,表示強(qiáng)行解包
    • 如果有值涮因,會取值废睦,然后參與后續(xù)計算
    • 如果為 nil,強(qiáng)行解包會導(dǎo)致崩潰
print(x! + y! + z!)

程序員要對每一個 ! 負(fù)責(zé)

可選解包

  • 如果只是調(diào)用可選項的函數(shù)蕊退,而不需要參與計算郊楣,可以使用可選解包
  • 在可選項后,使用 ? 然后再調(diào)用函數(shù)
  • 使用可選解包可以:
    • 如果有值瓤荔,會取值净蚤,然后執(zhí)行后續(xù)函數(shù)
    • 如果為 nil,不會執(zhí)行任何函數(shù)
var optionValue: Int?
print(optionValue?.description)
// 輸出 nil

optionValue = 10
print(optionValue?.description)
// 輸出 Optional("10")

與強(qiáng)行解包對比输硝,可選解包更安全今瀑,但是只能用于函數(shù)調(diào)用,而不能用于計算

Paste_Image.png

可選項判斷

不強(qiáng)行解包的方法

由于可選項的值可能為 nil点把,不允許直接參與運算橘荠,因此在實際開發(fā)中,經(jīng)常需要判斷可選項是否有值郎逃。

如果單純使用 if哥童,會讓代碼嵌套層次很深,不宜閱讀和維護(hù)褒翰,為了解決這一問題贮懈,蘋果提供了以下三種方式:

  • ??
  • if let / var
  • guard let / var

??

  • ?? 運算符可以用于判斷可選項是否為 nil,如果是則使用后面的值替代

注意:?? 的優(yōu)先級低优训,在使用時朵你,應(yīng)該注意使用 ()

let x: Int? = 10
let y: Int? = 100

print((x ?? 0) + (y ?? 0))

if let / var

  • 使用 if let,一旦進(jìn)入 if 分支揣非,表示可選項一定有值
  • 常量/變量的作用域僅在 {} 內(nèi)部
  • 使用 , 可以判斷多個可選項是否有值
  • 使用同名常量/變量抡医,避免再次起名的煩惱
  • 如果要在分支邏輯中修改值,可以使用 var早敬,通常使用 let
let name: String? = "Mike"
let age: Int? = 18

if let name = name,
    let age = age {
    print("\(name) 今年 \(age) 歲")
} else {
    print("姓名或者年齡為 nil")
}

guard let / var

  • guard 是與 if let 相反的語法忌傻,Swift 2.0 推出
  • guard 同樣可以判斷可選項是否有值
  • 多值判斷使用 , 分隔
  • 如果發(fā)現(xiàn) nil,在 else 分支返回
  • 分支結(jié)束后搞监,所有的 常量/變量 都有值
  • 相比較 if let水孩,guard 語法的分支結(jié)構(gòu)能節(jié)省一層
  • 如果要在后續(xù)邏輯中修改值,可以使用 var腺逛,通常使用 let
func demo(name: String?, age: Int?) {

    guard let name = name,
        let age = age else {
            print("姓名或者年齡為 nil")

            return
    }

    print("\(name) 今年 \(age) 歲")
}

demo(name: name, age: age)

guard let和if let可以用同名變量接收荷愕。

因為總會取名字衡怀,if let name = name這樣就可以,注意后面使用的時候用非空的那個安疗!并且iflet和guardlet可以依次判斷抛杨,先判斷是一個字典,再拿字典的數(shù)組荐类,在判斷數(shù)組的值怖现,可以一條線判斷出來。


四玉罐、字符串

用String屈嗤,是一個結(jié)構(gòu)體,具有絕大多數(shù)NSString功能吊输,支持直接遍歷

(1)遍歷:

func demo3() {
    
    // 字符串遍歷(NSString不支持這么遍歷)
    let str = "wowosnshi是"
    
    for s in str.characters {
        print(s)
    }
}

(2)長度:

// 返回指定編碼對應(yīng)的字節(jié)數(shù)饶号,每個漢字三個字節(jié)
print(str.lengthOfBytes(using: .utf8))

// 返回真正字符串長度
print(str.characters.count)

(3)拼接:要注意可選項拼接不解決會帶上Optional,剩下的都可以拼接季蚂,再也不用看StringWithFormat了

let name = "AA"

let age = 19

let title : String? = "sss"

print("\(name)\(age)\(title ?? "")")

(4)格式化:

  • 格式化成日期
let h = 8 , m = 10, s = 44

// OC中用stringWithFormat格式化日期茫船,Swift中可以

let strDate = String(format: "%02d-%02d-%02d", h,m,s)

print(strDate)

(5)截取字符串:建議用NSStrin作中轉(zhuǎn),因為swift取串方法一直在改變

  • NSString方法
let str = "紅紅火火恍恍惚惚"

let strOC = str as NSString

strOC .substring(to: 1)

strOC.substring(with: NSMakeRange(0, 2))

五扭屁、數(shù)組

(1)就是中括號算谈,注意數(shù)組的類型,并且基本數(shù)據(jù)類型不需要包裝料滥,可以直接方數(shù)組里然眼,如果類型不一樣(混合數(shù)組,但是基本不用)葵腹,自動推導(dǎo)[NSObject]高每。在Swift中還有一個[AnyObject類型],標(biāo)示任意對象礁蔗,因為在Swift中一個類可以沒有任何父類觉义。

(2)遍歷:

    // 遍歷1(按照下標(biāo)遍歷)
    for i in 0..<array.count {
        
        
    }
    
    // 遍歷2(遍歷元素)
    for s in array {
        
             
    }
    
    // 遍歷3(同時遍歷下標(biāo)和元素)
    for e in array.enumerated() {
        
        // let e: (offset: Int, element: String) e是一個元組        
        print("\(e.offset), \(e.element)")
        
    }
    
    // 遍歷4(同時遍歷下標(biāo)和元素)
    for (n,s) in array.enumerated() {
        
        print("\(n),\(s)")
        
    }
    
    // 反序遍歷
    for s in array.reversed() {
        
                
    }
        
    // 反序索引下標(biāo)(這樣寫才對雁社,先枚舉再反序)
    for (n,s) in array.enumerated().reversed() {
        
        
    }

(3)增刪改:

    array.append("AA")
    
    array[1] = "BBB"
    
    array.remove(at: 2)

(4)合并:用“+”號浴井。但是要合并的數(shù)組的兩個類型必須一致。

六霉撵、字典

一般是[String:NSObject]磺浙,對應(yīng)鍵值對.由于3.0后大部分都是結(jié)構(gòu)體了,AnyObject不好用了,Any范圍更大
(1)字典數(shù)組:
(2)增刪改:和數(shù)組都類似徒坡,就是兩個字典合并不像數(shù)組直接相加撕氧,而是需要遍歷

七、函數(shù)

(1)外部參數(shù)喇完,當(dāng)外部參數(shù)用_替代的時候伦泥,會在外部調(diào)用的時候忽略形參名


(2)函數(shù)的默認(rèn)值(OC不具備),這個使Swift比OC靈活很多很多,一個方法可以做很多事不脯,因為OC會有各種參數(shù)和組合府怯,Swift只需寫一個最多的參數(shù),然后不需要的設(shè)定默認(rèn)值就是了

(3)無返回值 :直接省略 () Void都可以

(4)閉包:類似Block防楷,比Block還廣泛牺丙。OC中Block是匿名函數(shù),Swift中函數(shù)是特殊的閉包复局。閉包在整個開發(fā)中和Block的應(yīng)用場景一樣冲簿。用于控制器/自定義視圖/異步執(zhí)行完成的回調(diào)。這些回調(diào)的特點就是都是以參數(shù)回調(diào)處理結(jié)果亿昏,返回值為Void峦剔。

  • 定義:
   let biBao = { (x: Int) -> Int in
            
       return x + 100
   }
        
   print(biBao(10))
  • GCD:將任務(wù)添加到隊列,指定執(zhí)行任務(wù)的函數(shù)角钩。任務(wù)就是Block/閉包羊异,隊列以同步/異步的方式執(zhí)行。
   func loadData(compeletion:@escaping ( _ result: [String])->()) -> Void {
       
       DispatchQueue.global().async {
           
           print("耗時操作會獲得一些結(jié)果 \(Thread.current)")
           
           Thread.sleep(forTimeInterval: 1.0)
           
           let json = ["天氣","不錯","刮大風(fēng)"]
           
           // 主線程回調(diào)
           DispatchQueue.main.async(execute: {
               
               print("主線程更新UI \(Thread.current)")
               
               // 回調(diào) -> 通過參數(shù)傳遞 執(zhí)行閉包
               compeletion(json)
           })
       }
  
   }

調(diào)用:

        // 執(zhí)行的適合我就拿到了值
        loadData { (result) in
            
            print("獲取的新聞數(shù)據(jù) \(result)")
        }

  • 尾隨閉包:如果函數(shù)的最后一個參數(shù)是閉包彤断,那么參數(shù)就省略了野舶,最后一個參數(shù)直接{}大括號包裝

  • 閉包的循環(huán)引用:

方法1
方法2

(5)面向?qū)ο螅ǜ鞣N構(gòu)造函數(shù)):()就是allocInit,在Swift中對應(yīng)init()宰衙。在swift中一個項目所有類都是共享的平道,可以直接訪問,每一個類都默認(rèn)有一個命名空間供炼。A.name B.name God.name Dog.name一屋。同一個類可以從屬于不同的命名空間(假如有一個框架有Person類,做用戶袋哼,還有一個框架做后臺冀墨,也用Person。在OC中就只能靠前綴解決涛贯,HouTaiPerson诽嘉,KuangJiaPerson。而Swift中的命名空間就是項目名弟翘。AAA項目有一個Person虫腋,那么AAA.Person就是AAA的Person類,此時再導(dǎo)入框架稀余,那也是框架的.Person)


  • 在自定義的Nsobjiect類中悦冀,has no initalizers 標(biāo)示沒有初始化器,初始化器可以有多個睛琳,默認(rèn)是init盒蟆。當(dāng)這個類有屬性的時候踏烙,屬性要分配內(nèi)存空間,就是說要有初始值历等。那么其實就是先給自己的屬性分配宙帝,然后給父初始。其實這么一看募闲,Swift和OC是相反的步脓!

思路:OC是先調(diào)用爸爸。就是Person浩螺,Person會再調(diào)用NSObject靴患,就是先跑上去什么都不管,先初始化了NSObject要出,然后才往下走挨個初始化鸳君。Swift是把自己完全初始化,再上去初始化爸爸患蹂,這么看比OC快了一圈或颊,性能要好。

  • 重載構(gòu)造函數(shù):(重寫是父類有這個方法传于,override囱挑。重載是函數(shù)名相同,參數(shù)和個數(shù)不同沼溜。init就重寫平挑,init+參數(shù)就重載。OC是沒有重載的系草!都是initWithXXXXX)通熄。重載其實是最基本的方式,OC沒有其實很low找都,但是Swift有唇辨。

注意:如果重載了構(gòu)造函數(shù)并且沒有實現(xiàn)父類的init,那么系統(tǒng)不再提供init構(gòu)造函數(shù)了(默認(rèn)是有的)能耻,因為默認(rèn)的構(gòu)造函數(shù)不能給本類的屬性分配空間(你不自己寫name = 赏枚,系統(tǒng)就沒辦法分配)

  • KVC構(gòu)造函數(shù):只需記住下面4點


    所以一般在模型中加個? 然后用KVC實現(xiàn)(先調(diào)用init因為是運行時機(jī)制)

  • 模型中屬性定義:基本數(shù)據(jù)類型 = 0嚎京,對象設(shè)置嗡贺?
    運行時中隐解,基本類型設(shè)置鞍帝? 屬性設(shè)置私有都會讓運行時拿不到,此時kvc就會出錯煞茫。


  • 如果子類沒有重寫父類方法帕涌,調(diào)用的時候就會直接調(diào)用父類的方法摄凡。當(dāng)繼承一個類,就繼承所有屬性和方法蚓曼,包括KVC亲澡。當(dāng)PERSON寫好了KVC后,

  • 整體



    (6)便利構(gòu)造函數(shù):關(guān)鍵字Convenience(開發(fā)用的很少纫版,因為模型都是框架轉(zhuǎn)床绪,UI不需要便利)
    *目的:條件判斷,只有滿足條件才實例化對象其弊,防止不必要的內(nèi)存開銷癞己,簡化對象創(chuàng)建。本身是不負(fù)責(zé)屬性的創(chuàng)建和初始化的梭伐。

(7)deinit:類似OC的Dealloc


八痹雅、分類:extension

便利構(gòu)造函數(shù) + 分類可以省略抽取很多代碼。例如給UITextField/UIButton寫分類糊识,然后寫便利構(gòu)造函數(shù)绩社,方便。

九赂苗、Swift的類愉耙,結(jié)構(gòu)體,枚舉三種都有構(gòu)造函數(shù)拌滋,都可以有方法劲阎,就像OC的類

十、其它

懶加載:

在OC開發(fā)中鸠真,懶加載一般自定義控件悯仙。在Swift中,懶加載還是需要用的吠卷,可以保證控件延遲創(chuàng)建锡垄,還能避免處理控件解包。如果直接定義控件var label = UILabel祭隔,根據(jù)代碼從上到下货岭,會讓控件在ViewDidLad之前就提前創(chuàng)建了。所以需要懶加載疾渴。OC中懶加載就是Get方法千贯,Swift直接lazy var。當(dāng)然也可以private lazy var來限定作用域搞坝。

(1)簡單的懶加載:


(2)完整的懶加載:()就是函數(shù)執(zhí)行搔谴,就是一個特殊的閉包紊遵,所以懶加載本質(zhì)是一個閉包夯秃。一般不這么寫难咕。



  
(3)OC和Swift區(qū)別

  • OC:
- (UILabel *)label{
    //如果label等于nil就會創(chuàng)建!
    if (_label == nil) {
        _label = [[UILabel alloc]init];
        _label.text = @"loirou";
        [_label sizeToFit];
        _label.center = self.view.center;
    }
    return _label;
}

OC是等于nil時候就懶加載

    [self.view addSubview:self.label];
    //釋放label
    _label = nil;
    
    //會再次調(diào)用懶加載的代碼
    NSLog(@"%@",self.label);

當(dāng)label設(shè)nil的時候就在此調(diào)用回怜。在ios6中,didReceiveMemoryWarning是不清理視圖的芜果。

  • Swift:

此時釋放的時候就會報錯鞠呈。因為定義的時候沒有?右钾,就是一定有值得蚁吝。
那么如果定義時候加? 一旦label = nil舀射,也不會在執(zhí)行懶加載了灭将!因為懶加載根本沒寫如果是空就創(chuàng)建。
懶加載只會在第一次調(diào)用的時候執(zhí)行閉包后控。Swift中一定注意不要主動清理視圖或控件庙曙,因為懶加載不會創(chuàng)建了(例如內(nèi)存警告別干掉控件,干掉了在也用不成了浩淘,因為懶加載就一次)

計算型屬性(只讀):

(1)getter/setter(開發(fā)不用):

    // 開發(fā)一般不用捌朴,還給搞一個_name。
    // swift一般不會重寫getter和setter
    private var _name: String? // 假裝的一個值
    var name: String? { get{return _name}  set{_name = newValue}} // get返回成員變量 set記錄成員變量

    override func viewDidLoad() {
        super.viewDidLoad()
        
        demo()
    }

}

(2)計算型屬性:readOnly只讀:OC中重寫get张抄。Swift也是重寫get砂蔽,不管set就可以。

  // 只讀署惯,此時set賦值時候就會報錯
   var name: String? { get{return "ABC"}}
  // 還有一種簡寫:
   var name: String? { return "ABC"}

看這類屬性左驾,是本身不保存內(nèi)容的,都是通過計算獲得結(jié)果极谊。就可以當(dāng)我就是個沒有參數(shù)只有返回值的函數(shù)9钣摇!我每次return值給你我的任務(wù)就完成了轻猖。每次你調(diào)用我這個屬性的時候帆吻,我都會進(jìn)行一次計算!都會執(zhí)行我的代碼然后return給你咙边。我自身不存儲的猜煮。

(3)懶加載和計算型屬性的區(qū)別:


(4)存儲型屬性:需要開辟空間,存儲數(shù)據(jù)败许。一般的屬性都是存儲型屬性(懶加載)

(5)存儲和計算都可以王带?或者不加∈幸螅看情況是不是必選

(四)Swift中設(shè)置模型數(shù)據(jù):
Swift做好模型后愕撰。別的控件拿到模型后,由視圖自己來顯示。此時在didSet里寫盟戏。就是替代OC的Setter方法绪妹。(OC的Setter要考慮_成員變量 = 值甥桂,而且如果是copy需要.copy柿究,而Swift不需要考慮一切)

命名空間:

  • 在同一個空間(項目),全局共享黄选。用第三方時蝇摸,如果直接拖拽,那就從屬于一個空間办陷,很有可能沖突貌夕,所以用Cocopod
  • 動態(tài)獲得命名空間(從info.plist加載),命名空間和項目名稱有關(guān)系民镜。info的Bundle name其實就是命名空間(一般寫的很奇怪 #(ProdectNmae))啡专。
    打印info
    print(Bundle.main.infoDictionary)


賦值

// 獲取命名空間的值,可選 let str = 
Bundle.main.infoDictionary?["CFBundleName"] as? String ?? ""                  
let con = NSClassFromString(str + "." + "ViewController") as? UIViewController.Type

反射機(jī)制:

對于任何類都可以知道類的所有屬性和方法制圈,對于任何對象都可以調(diào)用任何屬性和方法们童,這種動態(tài)獲取的信息和動態(tài)調(diào)用對象屬性方法的功能成java的反射機(jī)制(Swift也有了)

(1)在OC中利用反射機(jī)制

  • 利用NSClassFromString方法來使用字符串獲取類
  • 利用isMemberOfClass判斷是否是某一個類
  • 利用isKindOfClass判斷是否是某一個類的子類
  • 利用conformsToProtocol判斷對象是否遵守某一個協(xié)議
  • 利用respondsToSelector判斷是否實現(xiàn)了某一個方法
  • 利用performSelector或者objc_msgSend間接調(diào)用方法

(2)在Swift中利用反射機(jī)制類似。工作中用的很多很多鲸鹦。
場景:AppDelegate(OC中也用過慧库,利用NSClassFromString獲得類,然后設(shè)置根控制器馋嗜。但是Swift中多了一個命名空間寫法齐板。)

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
    window = UIWindow(frame: UIScreen.main.bounds)
    
    // 依據(jù)String名字拿到控制器(添加項目名稱,命名空間葛菇,不能有數(shù)字和特殊符號)
    // 返回的是AnyClass甘磨? 需要as?強(qiáng)轉(zhuǎn)
    // 控制器添加Type類型
    let rootControl = NSClassFromString("SwiftyDemo.ViewController") as? UIViewController.Type
    
    let vc = rootControl?.init()
    
    window?.rootViewController = vc
    
    window?.makeKeyAndVisible()
    
    return true
}

(3)第三方框架眯停,用了很多反射機(jī)制和工廠方法宽档,為了實現(xiàn)大量的解耦和封裝,很麻煩庵朝。一個方法可能跳10個方法10個控制器才寫了一個加法吗冤。但是如果涉及高級開發(fā)和封裝,必須要經(jīng)過這一步九府。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末椎瘟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子侄旬,更是在濱河造成了極大的恐慌肺蔚,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件儡羔,死亡現(xiàn)場離奇詭異宣羊,居然都是意外死亡璧诵,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進(jìn)店門仇冯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來之宿,“玉大人,你說我怎么就攤上這事苛坚”缺唬” “怎么了?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵泼舱,是天一觀的道長等缀。 經(jīng)常有香客問我,道長娇昙,這世上最難降的妖魔是什么尺迂? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮冒掌,結(jié)果婚禮上噪裕,老公的妹妹穿的比我還像新娘。我一直安慰自己宋渔,他們只是感情好州疾,可當(dāng)我...
    茶點故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著皇拣,像睡著了一般严蓖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上氧急,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天颗胡,我揣著相機(jī)與錄音,去河邊找鬼吩坝。 笑死毒姨,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的钉寝。 我是一名探鬼主播弧呐,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嵌纲!你這毒婦竟也來了俘枫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤逮走,失蹤者是張志新(化名)和其女友劉穎鸠蚪,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡茅信,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年盾舌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蘸鲸。...
    茶點故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡妖谴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出棚贾,到底是詐尸還是另有隱情窖维,我是刑警寧澤榆综,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布妙痹,位于F島的核電站,受9級特大地震影響鼻疮,放射性物質(zhì)發(fā)生泄漏怯伊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一判沟、第九天 我趴在偏房一處隱蔽的房頂上張望耿芹。 院中可真熱鬧,春花似錦挪哄、人聲如沸吧秕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽砸彬。三九已至,卻和暖如春斯入,著一層夾襖步出監(jiān)牢的瞬間砂碉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工刻两, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留增蹭,地道東北人。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓磅摹,卻偏偏與公主長得像滋迈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子户誓,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,446評論 2 359

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

  • Swift 簡介 查看Swift當(dāng)前版本 簡介 Swift 語言由蘋果公司在 2014 年推出饼灿,用來撰寫 OS X...
    mian小爬閱讀 343評論 0 1
  • Swift 介紹 簡介 Swift 語言由蘋果公司在 2014 年推出,用來撰寫 OS X 和 iOS 應(yīng)用程序 ...
    大L君閱讀 3,232評論 3 25
  • 常量&變量 簡單體驗 階段性小結(jié)var 定義變量厅克,設(shè)置之后可以修改let 定義常量赔退,設(shè)置之后不可以修改語句末尾不用...
    年輕在于折騰閱讀 349評論 0 1
  • 還未更新完畢,后面會持續(xù)增加內(nèi)容 常量&變量 什么是常量和變量 在Swift中規(guī)定:在定義一個標(biāo)識符時必須明確說明...
    chenfanfang閱讀 1,069評論 0 5
  • 情商(EQ)這個詞雖然不是今天才提及的,可更多的人只知道智商(IQ)硕旗,其實情商是在智商的基礎(chǔ)上體現(xiàn)出來的自...
    8e4e1f2838ba閱讀 299評論 0 0