黑马程序员-1.内存管理

一. OC的内存管理的过程

OC为每个对象提供一个内部计数器,这个计数器跟踪对象的引用计数,当对象被创建或拷贝时,引用计数为1,每次保持对象时,调用retain接口,引用计数加1,如果不需要这个对象时调用release,引用计数减1,当对像的引用计数为0时,系统就会释放掉这块内存,释放对象调用dealloc。

for example:

1.对象在完成创建的同时,内部会自动创建一个引用计数器,这个计数器,是系统用来判断是否回收对象的唯一依据,当我们的引用计数retainCount = 0的时候,系统会毫不犹豫回收当前对象

2.[对象 release]  reatinCount - 1

3.[对象 retain]   reatinCount + 1 ,返回self

4.我们的引用计数retainCount = 0的 对象就被销毁了

5.dealloc函数,当一个对象要被销毁的时候,系统会自动调用dealloc函数,通知对象你将要被销毁

内存管理原则(配对原则):只要出现了 new,alloc,retain,就一定配对出现一个release,autorelease

二.单个对象的内存管理

//定义了一个 Person类  
//Person.h
@interface Person : NSObject

@property int age;
- (void)run;
@end 

//Person.m
- (void)dealloc
{
    [super dealloc];
    
    NSLog(@"Person 被销毁了");
}

//重写description方法
- (NSString *)description
{
    return [NSString stringWithFormat:@"age = %d",_age];
}

- (void)run
{
    NSLog(@"人跑起来了");
}

于是在在主函数中开始了实验

测试1:

void test1()
{
    //retainCount = 1
    Person * p = [[Person alloc] init];

    //retainCount = 0
    //系统已经将p所指向的对象回收了
    //EXC_BAD_ACCESS 访问了不可访问的内存空间
    //被系统回收的对象我们称之为僵尸对象
    //默认情况下xcode为了提高编码效率,不会时时检查僵尸对象
    [p release];
 
    //不能调用run方法
    [p run];
 
}

结论:系统将对象回收后,对象变成僵尸对象,不能再调用对象方法

解决办法:如果你确定当前作用于中的对象已经不会再被使用了,为了防止野指针操作,通常我们会把不在使用的指针变量赋值为nil  p = nil;

测试2

void test2()
{

     //内存泄漏第一种情况
     //1
     Person * p = [[Person alloc] init];
     
     p.age = 20;
     NSLog(@"%@",p);
     //2
     [p retain];
     
     //3
     [p retain];
     
     //2
     [p release];
     
     //只要对象的retainCount != 0 就会一直存在在内存中
     //内存泄漏指的就是,不再被使用的对象,一直在内存中没有被销毁

    
     //内存泄漏第二种情况
     //retainCount = 1
     Person * p = [[Person alloc] init];
     p.age = 20;
     [p run];   
     p = nil;
     [p release];//[nil release];
     */

结论:在上面的实验中列出了两种内存泄漏的可能,1.retainCount 不等于0    2.空指针release

测试3:

void test4()
{
    //1
    Person * p = [[Person alloc] init];
    
    p.age = 20;
    NSLog(@"%@",p);
    
    //0
    [p release];
   
    [p retain];
}

结论:

野指针操作,当一个对象retainCount已经为0 时,调用retain方法,是不会使得对象起死回生的,同时还会发生野指针操作异常

三.多个对象的内存管理

刚刚只有一个人对象,现在添加一个Car对象,让Person类包含Car类

@interface Person : NSObject
{
    Car * _car;
}

- (void)setCar:(Car *)car;
- (Car *)car;
- (void)drive;

@end

为了防止内存泄漏,Person类销毁时,Car也销毁,于是重写了Person类的

- (void)dealloc
{
    //目的是要保证在p对象存在的时候,car对象一定存在
    //对象p被销毁的时候,
    [_car release]
    [super dealloc];
    NSLog(@"Person 被销毁了");
}

四.手动内存管理时出现类之间相互引用的问题

@property(nonatomic,retain) Car * car;

@property (nonatomic,assign)Person * person;

当出现两个类相互引用时,一定要有一个类使用

retain
时间: 2024-12-28 11:53:52

黑马程序员-1.内存管理的相关文章

黑马程序员-OC内存管理 @property的增强

涉及到内存管理,只读,多线程等很多功能时,setter和getter方法也就没那么简单了:当然@property依然强大,很好用: 1:内存管理相关参数: *:retain:  (如果是oc对象类型),生成的setter会自动release旧值,retain新值: *:assign:(适用于非oc对象)  这个是默认的值 *:copy:release旧值,copy新值: @property (retain) NSString *name; // 同类型的参数不能同时写 // @property

黑马程序员___OC__内存管理

内存管理 引用计数器 当一个对象被创建出来,就要分配给内存这个对象,当不用这个对象的时候,就要及时的回收,为了可以明确知道对象有没有被使用,就要用引用计数器来体现,只要计数器不为0,表明对象被使用中. 1.方法的基本使用 1> retain :计数器+1,会返回对象本身 2> release :计数器-1,没有返回值 3> retainCount :获取当前的计数器 4> dealloc * 当一个对象要被回收的时候,就会调用 * 一定要调用[super dealloc],这句调用

黑马程序员—17-oc内存管理

一.   内存管理基本原理 OC中内存管理机制的原理:对象的及时释放 l  什么是内存管理 Ø   移动设备的内存极其有限,每个app所能占用的内存是有限制的 Ø   当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间.比如回收一些不需要使用的对象.变量等 Ø   管理范围:任何继承了NSObject的对象,对其他基本数据类型(int.char.float.double.struct.enum等)无效 l  引用计数器: u  1.概念: 每个OC对象都有自己的

黑马程序员——OC内存管理

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 手动内存管理 *为什么要学习内存管理? ①由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的. ②当我们对Objective-C 的内存管理机制琢磨不透时,编写的程序经常内存泄漏或崩溃. ③当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间. *Object-C内存管理范围 只管理任何继承了NSObject的对象,不管理其他基本数据类型(int.

[黑马程序员]Objective-C 内存管理

引用计数器 每个OC对象都有自己的引用计数器,是一个整数表示对象被引用的次数,即现在有多少东西在使用这个对象.对象刚被创建时,默认计数器值为1,当计数器的值变为0时,则对象销毁. 在每个OC对象内部,都专门有4个字节的存储空间来存储引用计数器. 作用: 判断对象要不要回收的唯一依据就是计数器是否为0,若不为0则存在. 操作: 给对象发送消息,进行相应的计数器操作. Retain消息:使计数器+1,该方法返回对象本身 Release消息:使计数器-1(并不代表释放对象) retainCount消息

黑马程序员--Objective-C 内存管理我之见解

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- 内存管理 为什么要进行内存管理? 因为设备的内存空间是有限的,如果一直占用,而不回收空间,内存就会被一直占用,导致内存不足,  系统就会就会报警,严重的可能直接退出程序,因此,在软件开发过程中,需要进行内存管理,以保证高效快速的分配内存,

黑马程序员— OC内存管理

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 之前我们学习过C语言的内存剖析,对于iOS移动设备开发来说,内存是极其有限的,因此管理好内存是相当重要的当移动设备的程序占用太多内存无法释放,有可能就会导致我们平时经常会遇到的闪退现象,这时就需要回收一些不需要再使用的内存空间,比如不需要使用的对象或者变量. 管理范围:任何继承NSObject的对象,对其他的基本数据类型(int.char.float.double.struct.enum等)无

黑马程序员——交通灯管理

模拟实现十字路口的交通灯管理系统逻辑,具体需求如下: 异步随机生成按照各个路线行驶的车辆. 例如: 由南向而来去往北向的车辆 右转车辆 由东向而来去往南向的车辆 ---- 左转车辆 ... 信号灯忽略黄灯,只考虑红灯和绿灯. 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制. 具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑. 注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆. 每辆车通过路口时间为1秒(提示:可通过线程Sleep

黑马程序员-OC-内存管理(非ARC模式下)

------- IOS培训.android培训.java培训.期待与您交流! ---------- 管理范围:所有继承NSObject的类对象  内存泄露?内存泄露的后果?  自己申请的内存,没有释放  会使内存中存在很多的垃圾,浪费不必要的内存  1.应用计数器:用于计算对象被使用的次数,是一个整数(每个对象都有自己的引用计数器:占4个字节) (1)当使用alloc.new或copy创建新对象时,新对象的引用计数器被设置为1. (2)当引用计数器为0时,则此对象所占用内存就会被回收.(发送re