自学内容网 自学内容网

Swift开发总结

1.单例的实现

class Singleton {
    // 静态属性
    static let shared = Singleton()
    // 私有构造器,防止外部创建新实例
    private init() {
    }

    var someProperty: Int = 0

    func someMethod() {
        
    }
}
  1. static let shared = Singleton(): 声明一个静态的常量属性 shared,它是 Singleton 类型的单一实例。

  2. private init(): 将构造器设为 private,防止外部直接创建 Singleton 类的新实例。

  3. 在需要使用单例实例的地方,直接通过 Singleton.shared 进行访问和操作。

// 访问单例属性和方法
Singleton.shared.someProperty = 42
Singleton.shared.someMethod()
  • 线程安全: 由于 shared 属性是静态的常量,在多线程环境下也能保证只有一个单例实例。

  • 延迟初始化Singleton 类的实例会在第一次访问 shared 属性时才被创建,节省资源。

  • 可扩展性: 单例类可以像普通类一样添加属性和方法,满足不同的需求。

  • 可测试性: 由于构造器是 private 的,可以通过依赖注入的方式来测试使用单例的类。

2.struct 与 class 的区别

  • 值类型 vs 引用类型:

    • Struct 是值类型,当它被赋值给一个变量或常量,或者被传递给函数时,会创建一个新的副本。修改副本不会影响原始的 Struct 实例。
    • Class 是引用类型,当它被赋值给一个变量或常量,或者被传递给函数时,只会创建一个对该实例的引用。修改引用会影响原始的 Class 实例。
// Struct 示例
struct Person {
    var name: String
    var age: Int
}

var person1 = Person(name: "Alice", age: 30)
var person2 = person1
person2.name = "Bob"
print(person1.name) // Output: "Alice"
print(person2.name) // Output: "Bob"

// Class 示例
class Person {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

let person1 = Person(name: "Alice", age: 30)
let person2 = person1
person2.name = "Bob"
print(person1.name) // Output: "Bob"
print(person2.name) // Output: "Bob"
  • 继承:

    • Class 支持继承,可以创建子类并继承父类的属性和方法。
    • Struct 不支持继承,但可以使用协议来实现类似的功能。
  • 初始化:

    • class 在初始化时不能直接把 property 放在默认的 constructor 的参数里,而是需要自己创建一个带参数的 constructor。struct 可以把属性放在默认的 constructor 的参数里。
class Person {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

let person = Person(name: "Alice", age: 30)


struct Person {
    let name: String
    let age: Int
}

let person = Person(name: "Alice", age: 30)
  • deinit:

    • Class 支持 deinit 方法,可以在实例被销毁时执行清理操作。
    • Struct 没有 deinit 方法,因为它们是值类型,在超出作用域时会自动销毁。
// Class deinit 示例
class Person {
    var name: String

    init(name: String) {
        self.name = name
        print("Person \(name) was initialized.")
    }

    deinit {
        print("Person \(name) was deinitialized.")
    }
}

var person: Person? = Person(name: "Alice")
person = nil // Output: "Person Alice was deinitialized."

// Struct 没有 deinit
struct Person {
    var name: String
}

var person = Person(name: "Alice")
// No deinit called
  • 类型转换:

    • Class 支持类型转换,可以在运行时检查和转换类实例的类型。
    • Struct 不支持类型转换,因为它们是值类型,没有运行时类型信息。
// Class 类型转换示例
class Animal {}
class Dog: Animal {}
class Cat: Animal {}

let animal: Animal = Dog()
if let dog = animal as? Dog {
    print("It's a dog!")
} else if let cat = animal as? Cat {
    print("It's a cat!")
} else {
    print("It's an unknown animal.")
}
  • 内存管理:

    • Class 实例需要手动管理内存,通常使用引用计数或自动引用计数(ARC)机制。
    • Struct 实例的内存管理是自动的,它们被分配在栈上,不需要手动管理。
  •  struct 的 function 要去改变 property 的值的时候要加上 mutating,而 class 不用。
struct Person {
    var name: String
    var age: Int

    mutating func updateName(to newName: String) {
        name = newName
    }
}

var person = Person(name: "Alice", age: 30)
person.updateName(to: "Bob")
print(person.name) // Output: "Bob"
  • struct 会自动生成需要的构造方法(constructor),哪个属性没有赋初始值就会生成以哪个属性为参数的构造方法。
struct Person {
    let name: String
    let age: Int = 30
}

let person = Person(name: "Alice") // Can call the constructor with name parameter
  • Struct 不能被序列化成 NSData 对象,原因是无法归解档。归解档的类必须遵守 NSCoding 协议,struct 不能遵守 NSCoding 协议。
  • 当项目的代码是 Swift 和 Objective-C 混合开发时,会发现在 Objective-C 的代码里无法调用 Swift 的 Struct。因为要在 Objective-C 里调用 Swift 代码的话,对象需要继承于 NSObject

总的来说,如果数据是简单的、不需要共享引用的,且不需要复杂的继承结构,使用 Struct 通常是更好的选择。而对于需要共享引用、继承、复杂内存管理的场景,使用 Class 会更合适。

未完待续。。。。。。


原文地址:https://blog.csdn.net/xiao2218897/article/details/140636500

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!