iOS 内存管理 引用计数器

程序的内存分配:

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。
2、堆区(heap)— 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。
3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的
全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域; 程序结束后由系统释放。
4、文字常量区,常量字符串就是放在这里的。程序结束后由系统释放。
5、程序代码区—存放函数体的二进制代码。

Objective-C使用的内存管理方式为引用计数。

ARC是iOS 5推出的新功能,全称叫 ARC(Automatic Reference Counting)。简单地说,就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。

首先引用计数器是针对堆中的对象进行的 + - 操作;retain +1 releaese -1 (堆以外的其他内存空间不可对计数器操 + - 作 ,栈中对象,即没有开辟内存的nil对象计数器始终为 0 ,常量区的对象 计数器始终为 -1)

例:(栈区对象 - 计数器始终为 0)

#import "ViewController.h"

@interface ViewController (){

    //编译时 存在栈中
    NSString *counter;
    NSMutableString *mutableCounter;

}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    counter = nil;
    [counter retain];

    mutableCounter = nil;
    [mutableCounter retain];

    NSLog(@"retainCount == %ld",counter.retainCount);

    NSLog(@"retainCount mutable== %ld",mutableCounter.retainCount);

    //打印结果
    //2022-06-21 09:11:09.087850+0800 Runloop[10250:111644] retainCount == 0

    //2022-06-21 09:15:42.783466+0800 Runloop[10448:118333] retainCount mutable== 0

}
@end

例:(常量区对象 - 计数器始终为 -1)

#import "ViewController.h"

@interface ViewController (){

    NSString *counter;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    counter = @"测试";
    [counter retain];


    NSLog(@"retainCount == %ld",counter.retainCount);

    //打印结果
    //2022-06-21 10:24:38.413376+0800 Runloop[12724:196910] retainCount == -1

}

例:(堆区对象 - retain +1 releaese -1)

#import "ViewController.h"

@interface ViewController (){

    //编译时在栈中
    NSMutableString *mutableCounter;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];


    //开辟堆中内存空间 引用计数器 +1
    mutableCounter = [[NSMutableString alloc] init];

    //retain 引用计数器 +1
    [mutableCounter retain];


    NSLog(@"retainCount mutable== %ld",mutableCounter.retainCount);

    //打印结果
    //2022-06-21 10:29:41.238208+0800 Runloop[12894:203132] retainCount mutable== 2

}

总结

栈区对象引用计数器一直为 0 ,不管有没有 retain releaese ;
常量区对象引用计数器一直为-1 ,不管有没有 retain releaese;
堆区对象引用计数器可进行 + - 操作;retain +1 releaese -1 。

文章持续更新中、希望对各位有所帮助、有问题可留言 大家共同学习.

你可能感兴趣的:(iOS 内存管理 引用计数器)