# 闲谈 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我直接面试,算是内推。😄

相关文章
相关标签/搜索