当前位置: 首页 > 工具软件 > Flying-Swift > 使用案例 >

Swift 基础03 —— Objective-C转战Swift

督飞羽
2023-12-01

枚举类型

import UIKit

// 1.枚举类型定义
enum MenthodType : String{
    case get = "get"
    case post = "post"
    case put = "put"
    case delete = "delete"
}

// 2.创建枚举具体的值
let type1 : MenthodType = .get
let type2 = MenthodType.get
let type3 = MenthodType(rawValue: "put")
let str = type3?.rawValue


// 3.给枚举类型进行赋值
enum Direction : Int{
    case east = 1
    case west = 2
    case north = 3
    case south = 4
}
let d1 : Direction = .east
let d2 = Direction(rawValue: 1)

// 4.枚举类型定义二:
enum Type : Int{
    case get = 0, post, put, delete
}
let t1 : Type = .get
let t2 = Type(rawValue: 1)

结构体

  • 结构体(struct)是由一系列具有相同或不同类型的数据构成的数据集合
  • 结构体指的是一种数据结构
  • 结构体是值类型,在方法中传递时是值传递
import UIKit

// 1.定义结构体
struct Location {
    // 属性
    var x : Double
    var y : Double
    
    // 方法
    func test() {
        print("结构体中的test函数")
    }
    // 改变成员属性,如果在结构体函数中修改了成员属性,那么该函数前必须加上mutating
    mutating func moveH(_ distance : Double) {
        self.x += distance
    }
    
    // 给结构体扩充构造函数
    // 1> 默认情况下,系统为每一个结构体提供一个默认的构造函数,并且该构造函数要求给每一个成员属性赋值
    // 2> 构造函数都是以init开头,并且构造函数不需要返回值
    // 3> 在构造函数结束时,必须保证所有的成员属性有被初始化
    init(x : Double, y : Double) {
        self.x = x
        self.y = y
    }
    init(xyStr : String) {
        let array = xyStr.components(separatedBy: ",")
        let item1 = array[0]
        let item2 = array[1]
        
        // ?? 判断前面的可选类型是否有值
        // 有值-解包,没有指-使用后面的值
        self.x = Double(item1) ?? 0
        self.y = Double(item2) ?? 0
    }
}

// 2.创建结构体对应的值
var center = Location(x: 20, y: 30)

// 3.系统结构体的创建方式
let rect = CGRect(x: 0, y: 0, width: 100, height: 100)
let size = CGSize(width: 20, height: 30)
let point = CGPoint(x: 0, y: 0)
let range = NSRange(location: 0, length: 3)

// 4.给结构体扩充方法
center.test()
center.moveH(20)

// 5.给结构体扩充构造函数
Location(x: 20, y: 30)

类的使用

类的定义

  • 定义的类,可以没有父类,那么该类是rootclass
  • 通常情况下,定义类时,继承自NSObject(非OC的NSObject)
import UIKit

// 1.如何定义类
/*
OC类的定义
@interface Person : NSObject
@end

@impelment
@end
*/
class Person {
    // 开发个人规范:
    // 1> 如果属性是值类型,则初始化为空值
    // 2> 如果属性是对象类型,则初始化为nil值
    var name : String = ""
    var age : Int = 0
    var view : UIView?
    
}

// 2.创建类的对象
let p = Person()

let view = UIView()
p.name = "aaa"
p.age = 18
p.view = view

类的属性

import UIKit

// 1.创建类
class Student {
    // 类的属性定义
    // 存储属性: 用于存储实例的常量&变量
    var name : String = ""
    var age : Int = 0
    var mathScore : Double = 0.0
    var chineseScore : Double = 0.0
    
    // 计算属性: 通过某种方式计算得来结果的属性
    var aveageScore : Double {
        return (chineseScore + mathScore) * 0.5
    }
    
    
    // 类属性
    static var courseCount : Int = 0
    
    // 给类扩充函数
    // 在OC中写的很多没有参数的方法,在Swift中可以写成计算属性
    /*
    func getAverageScore() -> Double {
        return (chineseScore + mathScore) * 0.5
    }
    */
}

// 2.创建类的对象
let stu = Student()
// 3.访问类属性
Student.courseCount = 2

监听属性的改变

import UIKit

class Person {
    var name : String = "" {
      	// 属性监听器
        // 1.监听属性即将发生改变
        willSet {
            print("属性即将发生改变\(name)")
            print(newValue)
        }
        // 2.监听属性已经发生改变
        didSet(oldName) {
            print("属性已经发生改变\(name)")
            print(oldName)
        }
    }
}

let p = Person()
p.name = "aaa"
p.name = "bbb"

类的构造函数

import UIKit
/*
 使用KVC的条件
 1> 必须继承NSObject
 2> 必须在构造函数中,先调用super.init()
 3> 调用setValuesForKeys
 4> 如果字典中n某一个key没有对应的属性,则需要重写setValue forUndefinedKey方法
 
 */

class Person : NSObject{
    var name : String = ""
    var age : Int = 0
    
    init(dict : [String : Any]) {
        /*
        if let name = dict["name"] as? String {
            self.name = name
        }
        if let age = dict["age"] as? Int {
            self.age = age
        }
         */
        super.init()
        setValuesForKeys(dict)
    }
    override func setValue(_ value: Any?, forUndefinedKey key: String) {
    }
}

let p = Person(dict: ["name" : "aaa", "age" : 18])

类的析构函数

import UIKit

class Person {
    var name : String = ""
    var age : Int = 0
    
    // 重写析构函数,监听对象的销毁
    deinit {
        print("Person --- deinit")
    }
}
var p : Person? = Person()
p = nil

自动引用计数

工作机制

  • Swift和OC一样,采用自动引用计数来管理内容
    • 当有一个强引用指向某个对象时,该对象的引用计数就回自动+1
    • 当该强引用消失时,引用计数会自动-1
    • 当引用计数为0时,该对象会被销毁

循环引用

import UIKit

/*
 OC中表示n弱引用
 __weak  __unsafe_unretained(野指针错误)
 Swift中表示弱引用
 weak  unowned(野指针错误)
 
 */

// 1.创建类
class Person {
    var name : String = ""
    var book : Book?
    deinit {
        print("Person --- deinit")
    }
}

class Book {
    var price : Double = 0.0
    weak var owner : Person?
    
    deinit {
        print("Book --- deinit")
    }
}

// 2.创建对象
var person : Person? = Person()
person!.name = "abc"
var book : Book? = Book()
book!.price = 60.0

person!.book = book
book!.owner = person

person = nil
book = nil

可选链

import UIKit

// 1.创建类
class Person {
    var name : String = ""
    var dog : Dog?
}

class Dog {
    var weight : Double = 0.0
    var toy : Toy?
}

class Toy {
    var price : Double = 0.0
    
    func flying() {
        print("flying...")
    }
}

// 2.创建类的对象
let p = Person()
p.name = "abc"
let d = Dog()
d.weight = 60.0
let t = Toy()
t.price = 100

p.dog = d
d.toy = t

// 3.可选链的使用
/* 不推荐,非常危险
let dog = p.dog
let toy = dog?.toy
let price = toy?.price
*/
/* 太麻烦
if let dog = p.dog {
    if let toy = dog.toy {
        let price = toy.price
    }
}
*/
// ?. 就是可选链,系统会自动判断可选类型是否有值,如果有值,则解包;如果没有值,则赋值为nil
// 注意:可选链获取的值,一定是可选类型
let price = p.dog?.toy?.price

// 如果可选链中有一个可选类型是没有值,那么这个语句不执行
p.dog?.toy?.price = 50

// 可选链调用方法
p.dog?.toy?.flying()

协议

import UIKit

// 1.协议的定义
protocol SportProtocol {
    // 默认情况下协议中的方法都是必须实现的方法
    func playBaskball()
    func playFootball()
}

// 2.定义类,并且遵守协议
class Teacher : SportProtocol {
    func playBaskball() {
        print("打篮球...")
    }
    
    func playFootball() {
        print("踢足球...")
    }
}
class Student : NSObject, SportProtocol {
    func playBaskball() {
        print("打篮球...")
    }
    
    func playFootball() {
        print("踢足球...")
    }
}
// 3.协议在代理设计模型中的使用
// 定义协议时,协议后面最好加上 class
// delegate的属性最好用weak,防止产生循环引用
protocol BuyTicketDelegate : class{
    func buyTicket()
}
class Person {
    // 定义代理属性
    weak var delegate : BuyTicketDelegate?
    
    func goToBeijing() {
        delegate?.buyTicket()
    }
}
// 4.如何让协议中的方法是可选方法
// optional属于OC特性,如果协议中有可选的方法,那么必须在protocol前面加上@objc,也是需要在optional前面加上@objc
@objc protocol TestProticol {
    @objc optional func test()
}

class Dog : TestProticol {   
}
 类似资料: