返回

iOS底层学习之weak原理探究

IOS

iOS底层学习之weak原理探究

iOS中的内存管理对于应用程序的稳定性和性能至关重要。在iOS中,ARC(Automatic Reference Counting)是一种自动化的内存管理技术,它通过跟踪对象的引用计数来管理内存。当对象的引用计数为零时,该对象将被自动释放,从而避免内存泄漏。

在ARC中,对象之间的引用关系主要通过strong、weak、unsafe_unretained三种来修饰。其中,strong关键字表示强引用,weak关键字表示弱引用,unsafe_unretained关键字表示非保留引用。

__strong

__strong关键字表示强引用,当对象被强引用时,对象的引用计数会增加1。当对象的强引用计数为零时,该对象将被自动释放。

class Person {
    let name: String

    init(name: String) {
        self.name = name
    }

    deinit {
        print("\(name) is being deallocated")
    }
}

var person: Person? = Person(name: "John")

// person强引用了Person对象,因此Person对象的引用计数为1
print(person!.name)

person = nil

// person不再强引用Person对象,因此Person对象的引用计数为0,Person对象被释放
// 打印输出:“John is being deallocated”

__weak

__weak关键字表示弱引用,当对象被弱引用时,对象的引用计数不会增加。当对象的强引用计数为零时,即使对象还有弱引用,该对象也将被自动释放。

class Person {
    let name: String

    init(name: String) {
        self.name = name
    }

    deinit {
        print("\(name) is being deallocated")
    }
}

var person: Person? = Person(name: "John")

// weakPerson弱引用了Person对象,因此Person对象的引用计数为1
var weakPerson: Person? = person

// person强引用了Person对象,因此Person对象的引用计数为2
print(person!.name)

person = nil

// person不再强引用Person对象,因此Person对象的引用计数为1
// weakPerson仍然弱引用Person对象,但Person对象的引用计数为1,因此Person对象不会被释放
// 打印输出:“John is still alive”
print(weakPerson!.name)

weakPerson = nil

// weakPerson不再弱引用Person对象,因此Person对象的引用计数为0,Person对象被释放
// 打印输出:“John is being deallocated”

__unsafe_unretained

__unsafe_unretained关键字表示非保留引用,当对象被非保留引用时,对象的引用计数不会增加。与weak引用不同的是,即使对象的强引用计数为零,对象也不会被释放。

class Person {
    let name: String

    init(name: String) {
        self.name = name
    }

    deinit {
        print("\(name) is being deallocated")
    }
}

var person: Person? = Person(name: "John")

// unsafePerson非保留引用了Person对象,因此Person对象的引用计数为1
var unsafePerson: Person? = person

// person强引用了Person对象,因此Person对象的引用计数为2
print(person!.name)

person = nil

// person不再强引用Person对象,因此Person对象的引用计数为1
// unsafePerson仍然非保留引用Person对象,但Person对象的引用计数为1,因此Person对象不会被释放
// 打印输出:“John is still alive”
print(unsafePerson!.name)

unsafePerson = nil

// unsafePerson不再非保留引用Person对象,但Person对象的引用计数为1,因此Person对象不会被释放
// 打印输出:“John is still alive”

总结

在iOS中,strong、weak、unsafe_unretained三种关键字用于修饰对象之间的引用关系。strong关键字表示强引用,weak关键字表示弱引用,unsafe_unretained关键字表示非保留引用。

  • 强引用会增加对象的引用计数,当对象的强引用计数为零时,该对象将被自动释放。
  • 弱引用不会增加对象的引用计数,当对象的强引用计数为零时,即使对象还有弱引用,该对象也将被自动释放。
  • 非保留引用不会增加对象的引用计数,即使对象的强引用计数为零,对象也不会被释放。

在实际开发中,开发者需要根据不同的需求来选择合适的引用类型。一般情况下,强引用用于持有对象,弱引用用于持有临时对象,非保留引用用于持有不会被释放的对象。