iOS 开发:iOS内存管理分析

2019-10-31  本文已影响0人  四月_Hsu

前言

本篇博客手动 copyiOS 开发:彻底理解 iOS 内存管理(MRC、ARC)。谢谢原作者的详细分析。

正文

一、什么是内存管理

综上所述,我们要对内存进行合理的内存分配、清除内存,回收哪些不需要在使用的对象,从而保证程序的稳定性。

那么,哪些对象需要我们进行内存管理呢?

这是因为:

示例:

int main(int argc, const char *argv []) {
    @autoreleasepool {
        int a = 10;  // 栈
        int b = 20;  // 栈
        // p: 栈
        // Person 对象(计数器 == 1):堆
        Person *p = [[Person alloc] init];
    }
    // 经过上面代码后,栈里的变量 a、b、p 都会被回收
    // 但是堆里的 Person 对象仍会留在内存中,因为它的计数器依然是 1
    return 0;
}
iOS内存管理-1

上述说法过于片面,其实并非所有 继承了 NSObject 的对象,存储在操作系统到 里边,譬如创建的字符串有时候根据创建方式、位置,也会存储到 常量区

二、内存管理模型

提供给 Objective-C 程序员的内存管理模型有一下三种:

三、 MRC 手动管理内存(Manual Reference Counting

1. 引用计数器

系统就是根据一个对象的引用计数器来判断什么时候需要回收一个对象的内存。

2. 引用计数操作
3. dealloc 方法
4. 野指针和空指针
5. 内存管理规律

单个对象内存管理规律

多个对象内存管理规律

6. @property 参数
7. 自动释放池

当我们不在使用一个对象的时候应该将其内存释放掉。但是有时候我们不知道应该何时将其释放,为了解决这个问题, Objective-C 提供了 autorelease 方法

7.1 使用 autorelease 有什么好处呢?
7.2 autorelease 的原理实质上是什么?

autorelease 实际上只是把 release 的调用延迟了,对于每一个 autorelease ,系统只是把对象放入了当前的 autorelease pool 中,当该 pool 被释放时,该 pool 中所有对象都会调用 release

7.3 autorelease 的创建方法
7.4 autorelease 的使用方法
7.5 autorelease 的注意事项
7.6 自动释放池的嵌套调用
7.7 autorelease 错误用法
8. MRC 中避免循环 retian

四、ARC 自动管理内存(Automatic Reference Counting

4.1 ARC 的判断原则

ARC 通过判断对象是否被 强指针 引用来决定引用计数是否增加。

4.2 ARC 的使用
int main(int argc, const char * argv[]) {
    // 不用写release, main函数执行完毕后p会被自动释放
    Person *p = [[Person alloc] init];

    return 0;
}
4.3 ARC 的注意点
4.4 ARC 下对象内存管理
4.5 ARC 下多对象内存管理

ARCMRC 一样,想拥有某个对象必须用强指针保存对象,但是不需要在 deallocrelease

@interface Person : NSObject
// MRC写法
//@property (nonatomic, retain) Dog *dog;

// ARC写法
@property (nonatomic, strong) Dog *dog;
@end
4.6 ARC 中的 @property 参数
4.7 ARC 下循环引用问题

ARCMRC 一样,如果 A 拥有 BB 拥有 A,那么必须一方使用弱指针。

@interface Person : NSObject
@property (nonatomic, strong) Dog *dog;
@end

@interface Dog : NSObject
// 错误写法, 循环引用会导致内存泄露
//@property (nonatomic, strong) Person *owner;

// 正确写法, 当如果保存对象建议使用weak
@property (nonatomic, weak) Person *owner;
@end

后记

最近两年一直在使用 Swift,对 OC 的一些基础知识遗忘了不少,通过这篇博客算是温习一些。接下来打算在细读一遍 《Objective-C高级编程》,来对 ARCBlocksGCD 做一个系统的复习。

上一篇下一篇

猜你喜欢

热点阅读