Swift和SwiftUI

1.Swift相對與OC一些更好用的特性
(1)更好用的switch...case,for循環,枚舉,結構體
a. switch...case
不需要break,一個case可以寫多個條件,使用fallthrough繼續執行

let num = arc4random() % 10
switch num {
case 1, 2:
    print("1, 2")
case 3..<5:
    print("3, 4")
case ..<7:
    print("6")
case ...8:
    print("8")
default:
    print("defalut")
}

基本數據類型都能判斷,并且能使用where語句

let testArray = [1,2,3]
switch testArray {
case let array1 where array1.first == 1:
    print(array1.first!)
default:
    print(testArray)
}

b. for循環
普通for循環

for i in 0..<8 {
    
}

for i in 0..<8 where i % 2 == 0 {
    
}

for i in (0..<8).reversed() {
    
}

for i in stride(from: 0, to: 8, by: 2) {
    
}

for i in stride(from: 0, through: 8, by: 2) {
    
}

集合類型的遍歷

// 數組遍歷
var array = [1,2,3,4]
for item in array {
    
}

for (i, item) in array.enumerated() {
    
}

for item in array {
    array.append(item)
}

// 數組的函數式
let mapArray = array.map { (item) -> Int in
    return item + 1
}

let filterArray = array.filter { (item) -> Bool in
    return item % 2 == 0
}

let reduce = array.reduce(3) { (item1, item2) -> Int in
    return item1 + item2
}

let sortArray = array.sorted { (item1, item2) -> Bool in
    return item1 > item2
}

// 數組的截取
let index4 = 2
let array4 = [1,2,3,4,5]
let subArray4 = array4[0..<index4]

// 字典遍歷
let dictionary = ["one": 1, "two": 2, "three": 3]
for (key, value) in dictionary {
    print(key, value)
}

c 枚舉

// Swift的枚舉可以和整型,浮點數,字符串,布爾類型關聯,不寫默認關聯字符串
enum Language: String {
        case Swift
        case ObjectiveC = "Objective-C"
        case C
        case Java
    }
print(Language.Swift.rawValue)
Language.init(rawValue: "Swift")

// 可以綁定值
enum RequestResult {
    case Success(Int)
    case Error(String)
}

let requestResult = RequestResult.Success(1)
switch requestResult {
case .Success(let code):
    print(code)
case .Error(let errorTint):
    print(errorTint)
}

// 可以定義方法和計算型屬性
enum Device {
    case iPad, iPhone, AppleTV, AppleWatch
    func introduced() -> String {
        switch self {
        case .iPad: return "iPad"
        case .iPhone: return "iPhone"
        case .AppleWatch: return "AppleWatch"
        case .AppleTV: return "AppleTV"
        }
    }
    
    var year: Int {
        switch self {
        case .iPhone: return 2007
        case .iPad: return 2010
        case .AppleTV: return 2011
        case .AppleWatch: return 2012
        }
    }
}
let introduce = Device.iPhone.introduced()

d 結構體
結構體在Swift中的地位很重要,Array Dictionary Set Int Float Double Bool String都是結構體

/*
  什么時候用結構體,什么時候用類
  把結構體看做值
  位置(經緯度)坐標(二維坐標,三維坐標)溫度
  把類看做是物體 人 車 動物
 */
/*
  結構較小,適用于復制操作,相比一個class的實例被多次引用,struct更加安全
無須擔心內存泄漏或者多線程沖突問題
*/
struct Location {
    var longitude: Double
    var latitude: Double
    
    // 使用Failable-Initializer
    init?(coordinateString: String) {
        // 非常簡潔的非空判斷,安全可靠
        guard
            let commaIndex = coordinateString.index(of: ","),
            let firstElement = Double(coordinateString[coordinateString.startIndex..<commaIndex]),
            let secondElement = Double(coordinateString[coordinateString.index(commaIndex, offsetBy: 1)..<coordinateString.endIndex])
            else {
                // 可能會失敗的init return nil
                return nil
        }
        
        self.longitude = firstElement
        self.latitude = secondElement
        
    }
}

(2)String與NSString

// 1.String拼接用“+”,NSString是引用類型, String是值類型
let string1 = "Hello Swift"
let string2 = "Good"
let string3 = string1 + string2

// 2.獲取的長度不同
let string4 = "你好,我來了a??"
let string5: NSString = "你好,我來了a??"
print(string4.count, string5.length)

// 3.獲取字字符串
let range: NSRange = string5.range(of: "??")
let subString5 = string5.substring(with: range)
print(subString5)

let range2 = string4.range(of: "??")
let subString4 = string4[range2!]
print(subString4)

// 4.它們的長度都是1,基于unicode編碼,不同的單個字符長度不一樣,不能使用string[index]的方式訪問單個字符,使用string.startIndex string.endIndex 構成前閉后開的區間 [startIndex, endIndex)
let subString4a = string4[string4.index(before: string4.endIndex)]
print(subString4a)
let subString4b = string4[string4.startIndex..<string4.index(string4.startIndex, offsetBy: 3)]
print(subString4b)

// 5.String字符串遍歷
for charater in string4 {
    print(charater)
}

// NSString 有一個方法isEqualToString 方法用來判斷兩個字符串是否完全相等,String沒有這個方法,但是因為String是值類型所以可以直接用 == 判斷是否完全相等 

(3)函數

let testString = "林哲生"
//(4)函數
func sayHello(name: String = testString, greeting: String = "你們好啊", extra: Dictionary<String, String>? = nil) {
    print(name + greeting)
}

/*
 1.支持重載
 2.函數參數可設置默認值
 */
sayHello()
sayHello(name: "1")
sayHello(greeting: "2")
sayHello(extra: ["one": "1"])

// 改變外部傳入的參數
var array = [1,2,3,4]
func sayHello(array: inout [Int]) {
    array.append(5)
}

(4)可選項,安全的語言

var string1: String? = "Hello"
var string2: String? = "Hi"

// 解包判斷1
if let string1 = string1 {
    print(string1)
}

func sayHello(name: String = "林哲生", greeting: String = "你們好啊", extra: Dictionary<String, String>? = nil) {
    // 解包判斷2
    guard let uExtra = extra else {
        return
    }
    
    print(uExtra)
}

func sayHello(greeting: String = "你們好啊", extra: Dictionary<String, String>? = nil) {
    // 解包判斷2
    guard let uExtra = extra else {
        return
    }
    
    print(uExtra)
}

// 強解包,給與默認值

(5)各種各樣的基類
NSObject(OC中所有的類都是繼承NSObject) < AnyObject(Swift中的類可以不繼承任何類) < Any(包含了函數的類型)

(6)基本數據類型都是值類型,copy - on - write

// 值類型
var arrayA = [1, 2, 3]
var arrayB = arrayA
arrayA.append(4)
arrayB.append(5)
print(arrayA)
print(arrayB)

// copy - on - write
let arrayA = [1, 2, 3]
var arrayB = arrayA
arrayA.withUnsafeBytes { print($0) }
arrayB.withUnsafeBytes { print($0) }
arrayB.append(4)
arrayB.withUnsafeBytes { print($0) }

2.Swift的動態性
(0)大綱
a 純Swift的類和繼承自NSObject的類通過runtimeAPI獲取方法屬性
b @objc之后可以被runtimeAPI獲取到,但是方法無法被替換
c dynamic后方法動態調用,可以被替換
d Swift和OC相互調用,Swift在OC類中的名字
e Swift使用關聯對象
f Swift5.0方法交換,動態訪問屬性(動態傳遞參數,動態調用方法)

(1)使用runtime API與Swift
a. @objc本意是讓OC可以調用Swift的方法,@objc所修飾的屬性,方法不能包含Swift特有的類
b. @objc 信息能使用runtime獲取,dynamic動態調用
c. 如果類繼承自Object-c的類會自動被編譯器插入@objc標識

class TestSwiftClass {
    var aBool: Bool = true
    var aInt: UInt = 0
    var aFloat: Float = 123.45
    var aDouble: Double = 1234.567
    var aString: String = "abc"

    @objc func printHaha() {
        print("Haha")
    }

    @objc func printHeihei() {
        print("Heihei")
    }
}

class TestObject: NSObject {
    var aBool: Bool = true
    var aInt: UInt = 0
    var aFloat: Float = 123.45
    var aDouble: Double = 1234.567
    var aString: String = "abc"

    override var description: String {
        return "TestObject"
    }

    func testReturnVoid() {

    }

    @objc dynamic func testdescription() -> String {
        return "testdescription"
    }
}

// 1 獲取類所有的屬性,方法
showClassRuntime(anyClass: TestSwiftClass.self)
showClassRuntime(anyClass: TestObject.self)

// 2 交換方法 ,加@objc可以獲取到
methodSwizzle(cls: TestObject.self, originSelector: #selector(getter: NSObjectProtocol.description), swizzleSelector: #selector(TestObject.testdescription))
let testObject = TestObject()
print("testObject:"+testObject.description)

// 3 加  dynamic 方法會被動態調用
methodSwizzle(cls: TestObject.self, originSelector: #selector(TestObject.testdescription), swizzleSelector: #selector(getter: NSObjectProtocol.description))
let testObject2 = TestObject()
print(testObject2.testdescription())

a .純 Swift 類沒有動態性,但在方法、屬性前添加 dynamic 修飾可以獲得動態性。
b .繼承自 NSObject 的 Swift 類,其繼承自父類的方法具有動態性,其他自定義方法、屬性需要加 dynamic 修飾才可以獲得動態性。
c .若方法的參數、屬性類型為 Swift 特有、無法映射到 Objective-C 的類型 (如 Character、Tuple),則此方法、屬性無法添加 dynamic 修飾(會編譯錯誤)
d .Swift 類在 Objective-C 中會有模塊前綴
e .仍然可以使用關聯對象技術

(2)Swift5的“Method Swizzling”

// 可繼承
@dynamicMemberLookup
class SwiftClass: NSObject {
    dynamic func sayWordsA() {
        print("A")
    }
    
    subscript(dynamicMember member: String) -> String {
        let properties = ["nickName": "Zhou", "city": "GuangZhou"]
        return properties[member] ?? "good"
    }
    
    subscript(dynamicMember member: String) -> Int {
        let properties = ["nickName": 1, "city": 2]
        return properties[member] ?? 3
    }
}


extension SwiftClass {
    @_dynamicReplacement(for: sayWordsA())
    func sayWordsB() {
        sayWordsA()
        print("B")
    }
    
    @_dynamicReplacement(for: sayWordsA())
    func sayWordsC() {
        sayWordsA()
        print("C")
    }
}

extension SwiftClass {
    var goodString: String? {
        get {
            return objc_getAssociatedObject(self, "goodString") as? String
        }
        
        set {
            objc_setAssociatedObject(self, "goodString", newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY_NONATOMIC)
        }
    }
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容

  • Swift1> Swift和OC的區別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,120評論 1 32
  • 前言:面試筆試都是必考語法知識點。請認真復習和深入研究OC。 目錄:iOS-面試題-OC基礎篇 (1) - (84...
    麥穗0615閱讀 4,264評論 0 33
  • Swift2.0 1.defer譯為延緩、推遲之意類似棧 注意作用域,其次是調用順序——即一個作用域結束(注意),...
    zeqinjie閱讀 3,386評論 0 50
  • 記得,剛來單位的時候,因為工作的原因,經常和領導出去辦事,有一次,領導對我說:"我發現你有個很大的問...
    L悶兒閱讀 469評論 0 0