OC和Swift比較

OC與swift

1.協(xié)議

OC:主要用來(lái)傳值

swift:不僅可以用來(lái)傳值,swift中的協(xié)議可以定義屬性方法,并且其協(xié)議可以進(jìn)行擴(kuò)展,在擴(kuò)展中還可以有自己的默認(rèn)實(shí)現(xiàn),這個(gè)特性使其可以面向協(xié)議的時(shí)候非常強(qiáng)大。

例:

//如果遵守了swift中的協(xié)議,那么里邊的非擴(kuò)展方法必須實(shí)現(xiàn)
protocol AnimationProtocol {
    //最大年齡(屬性方法)
    var maxAge: Int {get}
    
    //動(dòng)物都有自己的名字
    func name()
}

//swift中的協(xié)議支持?jǐn)U展,并且可以再擴(kuò)展中直接實(shí)現(xiàn)具體內(nèi)容(擴(kuò)展中不可以定義屬性方法),似乎跟OC中的繼承一樣
extension AnimationProtocol {
    func eat() {
        print("eat");
    }
}


class Dog: AnimationProtocol {
    //maxAge必須實(shí)現(xiàn)
    var maxAge: Int {
        get {
            return 20
        }
    }
    
    //name必須實(shí)現(xiàn)
    func name() {
        print("name: dog")
    }
    
    //可以實(shí)現(xiàn)也可以省略(類似繼承中的復(fù)寫(xiě))
    func eat() {
        print("eat shit")
    }

}

class Cat: AnimationProtocol {
    
    var maxAge: Int {
        get {
            return 10
        }
    }
    
    func name() {
        print("name: cat")
    }
}

使用繼承很容易出現(xiàn)父類越來(lái)越臃腫特別是多重繼承時(shí),最終變成方法垃圾場(chǎng)的情況;
但是利用swift的協(xié)議,可以實(shí)現(xiàn)類似于繼承的功能,但是比繼承更加靈活;當(dāng)某幾個(gè)類有共同特性的時(shí)候可以抽出一個(gè)協(xié)議,使用的時(shí)候遵守此協(xié)議即可,可以解放父類。

2.泛型

泛型在很多功能上看似可以用多態(tài)實(shí)現(xiàn),但還是有很多區(qū)別的。
自己目前為止的看法,如下是使用泛型的例子:

    static func set<T>(_ key: String, value: T) {
        let stdDefaults = UserDefaults.standard
        stdDefaults.set(_T<Any>.cast(value), forKey: key)
        stdDefaults.synchronize()
    }
    
    static func get<T>(_ key: String) -> T? {
        let stdDefaults = UserDefaults.standard
        let value: Any? = stdDefaults.value(forKey: key)
        return _T<T>.cast(value)
    }

那么如果將泛型改為多態(tài),如下:

    static func set(_ key: String, value: Any) {
        let stdDefaults = UserDefaults.standard
        stdDefaults.set(value, forKey: key)
        stdDefaults.synchronize()
    }
    
    static func get(_ key: String) -> Any? {
        let stdDefaults = UserDefaults.standard
        let value: Any? = stdDefaults.value(forKey: key)
        return value
    }

會(huì)有什么問(wèn)題呢?
一個(gè)簡(jiǎn)單的例子,如果我獲取的是一個(gè)model,那么如果是多態(tài),使用應(yīng)該是這樣的:

        let model = Model()
        SDB.set("model", value: model)
        let md = SDB.get("model") as? Model  //使用了as?說(shuō)明這是類型轉(zhuǎn)換

如果是泛型,使用應(yīng)該是這樣的:

        SDB_T.set("model", value: model)
        let md_t: Model? = SDB_T.get("model")  //前邊添加類型,屬于泛型的特征類型推斷
        
        //static func get<T>(_ key: String) -> T?

類型推斷是swift特有的,比如說(shuō)let str = "",swift可以推斷出str為String類型

下邊是一個(gè)項(xiàng)目中很有用的自定義去重算法:

    //去重算法 Equatable 判等協(xié)議
    func removalAlgorithm<T: Equatable>(a: [T], b:T) -> [T] {
        var items = a
        for i in 0..<a.count {
            let item = a[i]
            if item == b {
                items.remove(at: i)
            }
        }
        return items
    }

而mode中所要實(shí)現(xiàn)的協(xié)議如下:

class Model: Equatable {
    
    var mId: Int?
    var a: String?

    static func == (lhs: Model, rhs: Model) -> Bool {
        if lhs.mId == rhs.mId {
            return true
        }
        return false
    }
}

上邊的方法,如果不用泛型,想使用可能就比較麻煩了,需要各種類型轉(zhuǎn)換。

3.結(jié)構(gòu)體和類

oc和swift中結(jié)構(gòu)體何磊的類型是相同的,即結(jié)構(gòu)體是值類型,class是指針類型。
但是swift中結(jié)構(gòu)體更強(qiáng)大,可以實(shí)現(xiàn)很多類似于類的功能,目前swift中的Array,Dictory,String均為結(jié)構(gòu)體,因此這些常用的數(shù)據(jù)類型用法有比較大的差異。
String為例:
OC中兩個(gè)字符串對(duì)象是不可以直接用==進(jìn)行比較的,但是swift就可以(數(shù)組,字典同理)。
既然是值類型,那么有些運(yùn)算符就可以直接使用,如+:

    func test() {
        var arr1 = [1]
        let arr2 = [2]
        arr1 = arr1 + arr2
        print(arr1 == arr2)
    }

4.?&!

swift是類型確定型語(yǔ)言,對(duì)類型是否有值有嚴(yán)格要求,因此引入了?和!來(lái)對(duì)值進(jìn)行明確。
oc中如下:

- (NSString *)test {
    return nil;
}

這樣寫(xiě)在oc中是完全沒(méi)有問(wèn)題的,但是使用者可能就比較麻煩了,因?yàn)橥獠渴褂谜卟⒉荒艽_定這個(gè)有沒(méi)有值,因此每個(gè)使用此方法的人都需要去判斷返回值是否符合自己預(yù)期;

swift中如下:

    func test() ->String {
        //錯(cuò)誤的寫(xiě)法,編譯器會(huì)報(bào)錯(cuò)
        return nil
    }

這樣寫(xiě)在swift中是會(huì)報(bào)錯(cuò)的,因?yàn)槟愕姆祷刂礢tring沒(méi)有帶?因此默認(rèn)是一個(gè)非空的,所以此函數(shù)的作者就需要去考慮如果這兒是空或者這兒的類型不是我想要的,我要做哪些補(bǔ)救措施,其實(shí)就是從源頭上對(duì)一些錯(cuò)誤特別是野指針問(wèn)題做了預(yù)防。
那么在swift中怎么正確使用這一特性呢?
1.在某些場(chǎng)景下,你確定此函數(shù)會(huì)返回一個(gè)有效值,那么你就可以在返回值后邊加!或者默認(rèn)不加;

    func test() ->String {
        return ""
    }

2.有時(shí)候我們就是要告訴外邊,這個(gè)不一定是有效的,需要外部使用者自己處理,那就在返回值后便加?;

    func test() ->String? {
        return nil
    }

5.??

swift中多了一種??判斷符,它的作用類似三元運(yùn)算符,但是使用場(chǎng)景比較多的地方是對(duì)一個(gè)為空的值做詢問(wèn),如果為空怎么怎么樣,如下:

    func test(_ a :String?) ->String? {
        //如果a為空,則返回空字符串(其實(shí)這樣寫(xiě),返回值已經(jīng)不可能為空了)
        return a ?? ""
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,222評(píng)論 3 119
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 4,202評(píng)論 1 10
  • 參考資源《swifter》https://github.com/iOS-Swift-Developers/Swif...
    柯浩然閱讀 1,537評(píng)論 0 6
  • “長(zhǎng)官,王開(kāi)他們背叛了黑暗組織!”一個(gè)慌慌張張的聲音。一位小兵小跑著,來(lái)到了諾基的面前?!笆裁??你是怎么知道...
    夏小伙閱讀 549評(píng)論 1 3
  • 姓名:覃杏留 公司:河池南門時(shí)尚商貿(mào)有限公司 組別:258期利他二組 【日精進(jìn)打卡第0096天】 【知~學(xué)習(xí)】 誦...
    隔世的風(fēng)閱讀 317評(píng)論 0 0

友情鏈接更多精彩內(nèi)容