OC 知识复习 (六) 内存管理

20240202203641_image.png

20240202214314_image.png


20240202220341_image.png


20240202221308_image.png


20240202221459_image.png


20240202222245_image.png


20240202222616_image.png


20240202223127_image.png


20240202223710_image.png


20240202223727_image.png


20240202223830_image.png


20240202224326_image.png


20240202224702_image.png


20240202224800_image.png


20240202224856_image.png


20240202225934_image.png


20240202234222_image.png


20240202234612_image.png


20240202235053_image.png


20240202235446_image.png


20240202235715_image.png


在 Objective-C 中,strongretain 都是属性修饰符,它们的作用在内存管理方面非常相似。两者都会增加目标对象的引用计数,并保证目标对象在其作用域内不会被销毁。

但它们主要的区别在于:

  • strong 是 ARC (Automatic Reference Counting,自动引用计数) 环境下的术语。在 ARC 下,你不需要(实际上也不能)显式地调用 retainreleaseautorelease。ARC 会自动为你处理这些操作。当你声明一个 strong 属性,你告诉 ARC,这个属性对其指向的对象拥有所有权,直到这个属性的生命周期结束,ARC 才会自动释放该对象。

  • retain 则是 MRC (Manual Reference Counting,手动引用计数) 环境下的术语。在 MRC 下,你必须显式地管理你的对象的引用计数。当你声明一个 retain 属性,你告诉 MRC,当对象赋值给这个属性时,需要发送一个 retain 消息给这个对象,以防止它在你还需要使用它的时候被销毁。

如果你正在使用 ARC(这是现代 Objective-C 开发的标准),那么你应该总是使用 strong 而不是 retain


20240203002216_image.png

20240203002054_image.png

20240203002528_image.png 20240203002651_image.png

20240203002827_image.png

20240203003556_image.png


20240203003935_image.png

20240203004228_image.png

Objective-C 中的强指针和弱指针都被用于管理对象的内存生命周期。他们的底层实现主要基于 Objective-C 的自动引用计数(ARC)机制。

下面是对这两种指针类型的详细解释:

  1. 强指针 (Strong Pointer): 一个强指针持有它所指向的对象,只要至少有一个强指针正在引用一个对象,那么该对象就会保持在内存中。换句话说,当你将一个对象赋值给一个强指针时,这个对象的引用计数 +1,而当这个强指针被设置为 nil 或者重新赋值给其他对象时,原本被引用的对象的引用计数 -1。如果对象的引用计数变为0,那么这个对象就会被立即销毁。

    在 ARC 环境下,默认的属性关键字 @property (strong) 就代表强引用,例如:

    @property (strong, nonatomic) NSObject *obj;
    
    copy success
    1
  2. 弱指针 (Weak Pointer): 弱指针和强指针最大的区别在于,弱指针不持有它所指向的对象,也就是说,当你将一个对象赋值给一个弱指针时,这个对象的引用计数不会改变。因此,当一个对象没有任何强指针引用它的时候,即使还有弱指针引用着它,这个对象也会被销毁。并且,当对象被销毁后,所有引用该对象的弱指针会自动被设置为 nil,防止野指针出现。

    在 ARC 环境下,可以使用属性关键字 @property (weak) 来声明一个弱引用,例如:

    @property (weak, nonatomic) NSObject *obj;
    
    copy success
    1

整个强指针和弱指针的机制都是通过维护每个对象的引用计数来实现的,这种内存管理策略极大地简化了 Objective-C 的内存管理,减轻了程序员的负担。


是的,Objective-C 中对于单例对象也使用相似的规则。但是,由于单例对象的特性,其在程序运行期间会始终存在。

单例模式(Singleton Pattern)是一种常见的设计模式,它保证一个类仅有一个实例,并提供一个全局访问点来获取这个唯一的实例。对于单例对象,通常我们会通过静态方法获取这个单例实例,如果不存在则创建,如果已经存在则直接返回。

以下是一个 Objective-C 的单例实现示例:

+ (instancetype)sharedInstance {
    static dispatch_once_t onceToken;
    static MyClass *instance = nil;

    dispatch_once(&onceToken, ^{
        instance = [[MyClass alloc] init];
    });

    return instance;
}
copy success
1
2
3
4
5
6
7
8
9
10

在这个例子中,dispatch_once 函数确保了初始化代码只被执行一次,instance 是一个强引用的静态变量,所以单例对象在第一次创建后会始终存在,不会被 ARC 机制释放。

这就意味着,一旦单例对象被创建,它将在整个程序运行期间一直存在,除非程序结束或者你主动销毁它(但这很少见,也违背了单例的主要原则)。


20240203010903_image.png

20240203010356_image.png

20240203012034_image.png


20240203012305_image.png

20240203013911_image.png


20240203014830_image.png

20240203015251_image.png

因为分类中不能增加属性,所以自定义属性 必须要在本类中

20240203020316_image.png