黑马程序员-内存管理之引用计数器

1.引用计数器

  每种语言都有自己的内存管理机制,当然OC也不例外。当一个对象创建的时候,系统在堆中给这个对象分配了一块存储区域,这个对象被栈中的对象指针所指向,当没有任何指针指向这个对象的时候,系统怎么释放这块对象内存呢?OC中是用引用计数器来实现的。每一个对象拥有一个引用计数器(占四个字节),当对象被创建时,自带的引用计数器的值就为1了。给对象发送retain消息时,对象的引用计数器就做+1操作,表示有指针拥有这个对象,发送release消息时引用计数器做-1操作,表示某个指针不在拥有这个对象。当对象的引用计数器为0的时候,表示没有任何指针拥有这个对象,系统就会自动调用dealloc方法,销毁该对象。总体来说和c语言中的管理机制差不了多少,无非是多了一些方法调用。

  下面用代码演示一下,创建一个Person类,并对其操作。

1 #import <Foundation/Foundation.h>
2
3 @interface Person : NSObject
4
5 @property int age;
6
7 @end
 1 #import "Person.h"
 2
 3 @implementation Person
 4
 5 // 重写dealloc方法,当一个Person对象被回收的时候,就会自动调用这个方法
 6 - (void)dealloc
 7 {
 8     NSLog(@"Person对象被回收");
 9
10     // super的dealloc一定要调用,而且放在最后面
11     [super dealloc];
12 }
13
14 @end
#import <Foundation/Foundation.h>
#import "Person.h"

int main()
{
   // 对象创建的时候,引用计数器为1
    Person *p = [[Person alloc] init];

   // 获取引用计数器
    NSUInteger c = [p retainCount];
    NSLog(@"计数器:%ld", c);

    // 调用了retain方法,计数器变成了2
    Person *p2 = [p retain];

    // 调用了release方法,计数器变成了1
    [p release];

     // 调用了release方法,计数器变成了0,此时系统调用dealloc方法,  释放这块内存
    [p release];

    return 0;

注意:retain方法返回的是对象本身,因为它这个方法本身就是复制对象,如上述代码中的 Person *p2 = [p retain] 就是在栈中分配了一个内容为Person对象地址的指针,也就是指向了Person对象,此时Person对象的引用计数器必须+1,来标记有否个指针在拥有我。

2.野指针,空指针和僵尸对象。

1> 僵尸对象 :所占用内存已经被回收的对象,僵尸对象不能再使用

2>  野指针:指向僵尸对象(不可用内存)的指针,给野指针发送消息会报错(EXC_BAD_ACCESS)

3> 空指针:没有指向任何东西的指针(存储的东西是nil、NULL、0),给空指针发送消息不会报错

某些场合会引起僵尸对象和野指针的存在,要理解他们的概念。

时间: 2024-12-15 01:43:49

黑马程序员-内存管理之引用计数器的相关文章

黑马程序员----内存管理一《基本使用》

内存管理 1.为什么要进行内存管理 移动设备的内存极其有限,每个app所能占用的内存是有限制的: 当app所占用的内存较大时,系统就会发出内存警告,这时就的回收一些不需要使用的内存空间.比如:回收一些不需要的对象,变量等: 内存管理的范围:任何继承了NSObject的对象,对其他基本数据类型(int.char.float.double.struct.enum等)无效: 2.内存的基本结构 每个OC对象内部都有一个自己的引用计数器,是一个整数,表示:对象被调用的次数:即:有多少人正在使用这个OC对

黑马程序员-内存管理之autorelease和ARC机制

一.autorelease 之前我们都是手动release对象,但是有时候我们需要延迟release对象,这里我们就需要用到autorelease,系统会把当前对象放在当前的autorelease pool中,当autorelease pool销毁时,会把当前池子中的所有对象做一次release操作.对于每一个Runloop, 系统会隐式创建一个Autorelease pool,这些池子都是以栈结构的形式存在,在每一个Runloop结束时,当前栈顶的池子会被销毁,所有对象做一次release操作

黑马程序员----内存管理之五《ARC-自动引用计数》

内存管理之五<ARC-Automatic Reference Counting> 1.ARC概念 ARC是Automatic Reference Counting---自动引用计数. ARC是一种编译器特性,并不是java中得垃圾回收,java中的垃圾回收是运行时特性: ARC的判断准则:只要没有强指针指向对象,就会释放对象: 2.ARC的特点 不允许调用release.retain.retainCount: 允许重写dealloc方法,但是重写时不用再调用父类的dealloc方法 即 [su

黑马程序员----内存管理之二《多对象的内存管理》

内存管理之二——<多对象的内存管理> 1.多对象的内存管理方式: 只要有人使用了这个对象,这个对象就不能被销毁: 只要你想使用这个对象,就让这个对象的引用计数器的值+1(让对象做一次retain操作): 当你不再使用这个对象,就让这个的对象的引用计数器的值-1(让对象做一次release操作): 谁alloc,谁就release: 谁retain,谁就release: 2.内存管理的代码规范: 只要调用了alloc必须有release/autorelease set方法的代码规范: 1.基本数

黑马程序员----内存管理之四——《autorelease自动释放池》

内存管理之四——autorelease自动释放池 1.autorelease的基本使用 此对象方法会将对象放到一个自动释放池内: 当自动释放池被销毁时,就会对池子内的所有对象做一次release操作: 此方法会返回对象本身: 调用完此方法后,对象计数器的值不变,只有到自动释放池被销毁时才会对对象做一次release操作: 2.autorelease的好处 不用在关心对象被销毁的时间: 不用关心什么时候调用release操作: 3.autorelease的使用注意 占用内存较大的对象不要随便使用a

黑马程序员-内存管理

一. OC的内存管理的过程 OC为每个对象提供一个内部计数器,这个计数器跟踪对象的引用计数,当对象被创建或拷贝时,引用计数为1,每次保持对象时,调用retain接口,引用计数加1,如果不需要这个对象时调用release,引用计数减1,当对像的引用计数为0时,系统就会释放掉这块内存,释放对象调用dealloc. for example: 1.对象在完成创建的同时,内部会自动创建一个引用计数器,这个计数器,是系统用来判断是否回收对象的唯一依据,当我们的引用计数retainCount = 0的时候,系

黑马程序员----内存管理之三——《@property的内存管理》

内存管理之三——<@property的内存管理> 1.@property中与setter内存管理相关的参数 retain : release旧值,retain新值(适用于OC对象类型): assign : 直接赋值,(默认,适用于非OC对象类型): copy  : release旧值,copy新值: 2.@property中是否生成setter的参数 readonly  : 只会生成getter的声明和实现: readwrite : 同时生成setter和getter的声明和实现: 3.@pr

黑马程序员-内存管理之set方法内存管理

一.set方法内存管理 当一个对象拥有另一个对象的属性时,需要在set方法对当前所拥有的对象做retain操作,因为你的属性是指向了另一个对象,需要让另一个对象知道有单元在使用我. 但是这样写的话不够完善,会出现新的问题.如果对象属性之前已经指向了某一个对象了,此时再传进来一个新的对象,属性指针就指向了新的对象,然后retain了新的对象,但是旧的对象此时并没有人工release过,需要release一下.还有一个问题就是在release旧对象,retain新对象之前要做一个判断,判断一下此时拥

黑马程序员 内存管理之proterty,autorelease

#import <Foundation/Foundation.h> @interface Person : NSObject { Book * _book; int _age; } /* oc对象 [email protected]能制动生成setter和getter方法 2.retain告诉编译器自动生成setter里的retain 3.atomic:低性能(默认情况下) nonatomic:高性能 */ @property (nonatomic, retain) Book *book; /