# 閒談 Objective-C 與 Swift

bk
bk

我的博客git

隨着移動互聯網的發展,移動端iOS開發的技術選擇也劃分了好幾個方向,有用 React-Native進行開發的,有用 Objective-C開發的,也有用 Swift開發的,或者 混合 着來。github

不一樣的語言存在都有其可取的優秀之處,也有不足的地方。也應了那句俗話 : 金無足赤,人無完人。面試

咱們都知道 2014Swift 的橫空出世,其首要目的就是 劍指 Objective-C。 可是如今看來也沒有徹底達到其問世的目的。可是你們對於 Swift 的喜好依然是一路包容,好比從14年以來一年一學,其狀況猶如一年學習一門新語言,可是 Swift 也沒有讓咱們失望,一路高歌猛進,今年也迎來了 Swift 4, 從這一路上來看,有一部分人好多放棄在 Swift 2.X 的路上了,一部分人沒有體會到 Swift 3Swift 4 的喜悅. 也有一些人始終徘徊在 Swift 的門口; 一隻腳在裏面,一隻腳在外面。objective-c

從始至終堅持的人是抱着 「蘋果(Swift)」 虐我千百遍,我待 蘋果(Swift) 如初戀的執着,也正所謂: 撥開雲霧見天日 守得雲開見月明, 從目前來看 Swift 4 給了開發者很大的 支持與信心編程

兩種語言熟悉的人都知道 Objective-CSwift 底層是徹底不一樣的機制。json

Objective-C

Objective-C 的那一套跑不了 運行時, 我相信 KVC 的概念在每一個面試者的腦海中都能 信手拈來swift

KVC, NSKeyValueCoding,一個非正式的 Protocol,提供一種機制來間接訪問對象的屬性。
KVO 就是基於 KVC 實現的關鍵技術之一
以相似字典鍵值對的方式存儲信息,以及強大的動態派發,與 C 的結合
.......安全

太多太多bash

Swift

Swif 這門語言是偏偏不一樣,其類型成員在編譯的時候就已經決定,徹底是一門安全性的語言。
尤爲對協議的支持。好比對協議的實現有: 網絡

class struct enum

這裏不得不提到 enum 對協議的支持:

protocol Source {}

enum Action: Source {
    case handler(sender: UIButton)
    case touchUp(sender: UIButton)
}複製代碼

由此對協議的支持可見一斑。

蘋果在15年提出 Swift 的一種面向協議編程 (Protocol Oriented Programming)

protocol Work {}

extension Work {
    func doWork() {
        print("do Work")
    }
}

class action { }
extension action: Work {}

action().doWork()

// 結果
:do Work複製代碼

咱們看到這個 action 類,並無對協議進行任何代碼方面的書寫,而經過 extension 能夠直接爲協議進行擴展,並給出默認實現。這對於大量重複的代碼絕對是一個優秀的解決方案。
雖然在 Objective-C的時代就有 對重複代碼進行封裝經過繼承來實現也是一種解決方案。可是這種作法是有必定的風險的.

好比經過繼承的方式來:

class Action1: base1 {
    override func doWork() {
        print("do Work")
    }
}

class Action2: base1 {

}

Action2().doWork()

// 結果
:do Work複製代碼

貌似結果是同樣的,可是面對大量的代碼的時候結構構造的好處是顯而易見的,尤爲是協議的擴展:根據入口提供額外實現,也能夠提供默認的一個實現。往外每一個類都是經過其特定的組合方式來實現不一樣的業務需求的,若是經過以往的繼承方式構建在業務繁瑣的時候是沒法很好的對業務進行抽象封裝了,這個時候 Swift協議就能夠閃亮登場啦

其實寫過 C++ 的都知道支持多繼承,其帶來的風險也是顯而易見的:
好比:

class base1 {
    func doWork() {
        print("do Work")
    }
}

class Action1: base1 {
    override func doWork() {
        print("do Work")
    }
}

class Action2: base1 {
    override func doWork() {
        print("do Work")
    }
}

Action2().doWork()

class Commad: Action1,Action2 {

}

Commad().doWork()複製代碼

這種性質的繼承是致命的。固然 SwiftObjective-C 是不支持多繼承的,因此上面代碼是無效的。可是很重要的是 經過協議,並對協議進行默認實現也是能夠達到殊途同歸的多繼承做用。

Swift 與 Objective-C 混合

上面講過兩種語言的底層是徹底不一樣的,可是我相信混合開發的時候怎麼去處理呢?
尤爲是在 Objective-C 代碼中調用 Swift 的時候,Swift 沒有運行時這種東西,而OC調用混致使異常問題。這個時候咱們見到的 @objc 就自告奮勇了。

@objc

只有不是繼承 NSObjectSwift 寫的 Class 的非私有類型, 在 OC 中調用的時候都是須要加上這個標誌

Swift 創建模型

基於目前的習慣用到了 ObjectMapper

使用實例我相信官方介紹的比我詳細,我這裏就不作僭越 😄
我這裏代碼中放出一部分實例:

class HomeModel: Mappable {

    var money: NSNumber = 0      // 人民幣
    var hlbAmnt: NSNumber = 0    // 合鏈幣
    var etcAmnt: NSNumber = 0    // 以太經典
    var btcAmnt: NSNumber = 0    // 比特幣
    var ltcAmnt: NSNumber = 0    // 萊特幣
    var ethAmnt: NSNumber = 0    // 以太坊

    var btcAddress: String = ""     // 比特幣提幣地址

    var btcPercent: String = ""     // 比特幣資產百分率
    var totalMoney: NSNumber = 0    // 總資產
    var etcPercent: String = ""     // 以太經典的資產百分率
    var moneyPercent: String = ""   // RMB資產百分率
    var ltcPercent: String = ""     // 萊特幣的資產百分率
    var ethPercent: String = ""     // 以太坊的資產百分率
    var hlcPercent: String = ""     // 合鏈幣的資產百分率

    var frozeBtcAmnt: NSNumber = 0  // 凍結的BTC 的數量
    var frozeEtcaAmnt: NSNumber = 0 // 凍結的以太經典數量
    var frozeHlcAmnt: NSNumber = 0  // 凍結的合鏈幣數量
    var frozeEthAmnt: NSNumber = 0  // 凍結的以太坊數量
    var frozeLtcAmnt: NSNumber = 0  // 凍結的萊特幣數量

    var btcRate: String = ""        // 比特幣單價
    var etcRate: String = ""        // 以太經典單價
    var ethRate: String = ""        // 以太坊價格
    var ltcRate: String = ""        // 萊特幣價格
    var hlbRate: String = ""        // 合鏈幣價格


    required init?(map: Map) {

    }

    func mapping(map: Map) {
        money <- map["money"]
        hlbAmnt <- map["hlc_amnt"]
        etcAmnt <- map["etc_amnt"]
        btcAmnt <- map["btc_amnt"]
        ltcAmnt <- map["ltc_amnt"]
        ethAmnt <- map["eth_amnt"]

        btcAddress <- map["btc_address"]

        btcPercent <- map["btc_percent"]
        totalMoney <- map["totalMoney"]
        etcPercent <- map["etcPercent"]
        moneyPercent <- map["money_percent"]
        ltcPercent <- map["ltc_percent"]
        ethPercent <- map["eth_percent"]
        hlcPercent <- map["hlc_percent"]

        frozeBtcAmnt <- map["froze_btc_amnt"]
        frozeEtcaAmnt <- map["froze_etc_amnt"]
        frozeHlcAmnt <- map["froze_hlc_amnt"]
        frozeEthAmnt <- map["froze_eth_amnt"]
        frozeLtcAmnt <- map["froze_ltc_amnt"]

        btcRate <- map["btc_rate"]
        etcRate <- map["etc_rate"]
        ethRate <- map["eth_rate"]
        ltcRate <- map["ltc_rate"]
        hlbRate <- map["hlc_rate"]

    }
}複製代碼

那麼解析是這樣的:

struct ResultSum {
    var status: Bool = false
    var message: String = "未知錯誤"
    var property: HomeModel?

    init(data: Any) {
        let json = JSON(data)
        if json["errorCode"].intValue == 0 {
            status = true
            if let info = json["data"]["userWallet"].dictionaryObject {
                property = Mapper<HomeModel>().map(JSONObject: info)
            }
        }
        message = json["message"].stringValue
    }
}複製代碼

其中 property 是可選的,由於理想的狀況下才會成功,也有不返回的狀況。

這裏的網絡請求用到的是 POP (Protocol Oriented Programming) 思想。

Swift 隱式解包 多重 Optional

SwiftOptional

先看例子:

var searchController: UISearchController!

lazy var reducer: (State, Action) -> (state: State, command: Command?) = {
        [weak self] (state: State, action: Action) in
        var state = state
        var command: Command? = nil
        switch action {
        case .loadData:
            command = Command.loadCycleDate { self?.store.dispatch(.reloadCycleData(images: $0))}
        case .reloadCycleData(let items):
            state.cycleSource = CycleDataSource(images: items, collection: state.cycleSource.collectionView)
        case .selectCycleView(let index):
            command = Command.selectCycleView(index: index)
            break
        case .selectMenu(let index):
            command = Command.selectMenu(index: index)
        }
        return (state, command)
    }複製代碼

例如的示例中 Command?var searchController: UISearchController!

在對其成員或者方法調用的時候,編譯器會對其進行自動解包。!是用來告訴編譯器它是一個能夠隱式解包的 Optional 值。
使用的時候直接可使用,這種狀況若是 searchController 若是沒有被實例化的時候是 nil ,直接使用會致使程序直接崩潰,而使用的時候也會會被人誤覺得能直接訪問

好比使用相關操做的時候:

var searchController: UISearchController!

searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.searchBarStyle = .minimal

沒有實例化:直接崩潰 😖複製代碼

若是是 ?的時候

var searchController: UISearchController?

searchController?.searchResultsUpdater = searchResultsController
searchController?.hidesNavigationBarDuringPresentation = false複製代碼

在示例中 Command? 表示是一個可選空值,能夠是空,能夠用
if let 的 Optional Binding 來處理

if let resul = result, let models = resul.arrModel {
                if !resul.status { return }
            }複製代碼

像這些基本性的問題你能夠去 Objc 挑幾本看看。做者是一個值得敬重的人。

我這裏也無法在短期內細緻的介紹太多,還在招人,證實活比較多 (⊙﹏⊙)b

Swift 的世界有太多的東西,有時間在說

......

若是你看到這裏,插播一條廣告:

公司須要 須要 兩名iOS開發人員
座標:北京望京 Soho T3 30層
要求是:Swift, OC 都在中等以上,紮實的計算機基礎
公司不打卡,各類補貼,技術團隊來自知名企業:IBM,微軟,惠普,三星,百度等等 CTO 早年跟喬布斯有過合做。氛圍很好。 簡歷這裏: sirBliar@gmail.com我直接面試,算是內推。😄

相關文章
相關標籤/搜索