lijifeng

导航

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

                                                          (以下内容是对黑马苹果入学视频的个人知识点总结)

(一)计数器

     每个对象内部都保存了一个与之相关联的整数,称为引用计数器,当使用alloc、new或者copy创建一个对象时,对象的引用计数器被设置为1

1>给对象发送一条retain消息,可以使引用计数器值+1
2>给对象发送一条release消息,可以使引用计数器值-1
3>当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存被系统回收,系统也会自动向对象发送一条dealloc消息。一般会重写dealloc方法,在这里释放相关资源。一定不要直接调用dealloc方法
4>可以给对象发送retainCount消息获得当前的引用计数器值
 当一个对象要被回收的时候,就会调用
一定的[super dealloc]
 1 #import "Person.h"
 2 
 3 @implementation Person
 4 
 5 
 6 // 当一个Person对象被回收的时候,就会自动调用这个方法
 7 - (void)dealloc
 8 {
 9     NSLog(@"Person对象被回收");
10     
11     // super的dealloc一定要调用,而且放在最后面
12     [super dealloc];
13 }
14 
15 @end

2)内存的管理原则

1.谁创建,谁释放(“谁污染,谁治理”)。如果你通过alloc、new或(mutable)copy来创建一个对象,那么你必须调用release或autorelease。换句话说,不是你创建的,就不用你去释放

2.一般来说,除了alloc、new或copy之外的方法创建的对象都被声明了autorelease

3.谁retain,谁release。只要你调用了retain,无论这个对象是如何生成的,你都要调用release

注意:

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

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

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

3)多个对象之间的内存管理

1>使用(占用)某个对象,就应该让对象的计数器+1(让对象做一次retain操作)

2>你不想再使用(占用)某个对象,就应该让对象的计数器-1(让对象做一次release)

3>谁retain,谁release

4>谁alloc,谁release

int main()
{
   
    Book *b = [[Book alloc] init];
  
    Person *p1 = [[Person alloc] init];
    
    [p1 setBook:b];
    
    [p1 release];
    p1 = nil;
    
    [b release];
    b = nil;
    return 0;
}

(二)set方法的内存管理

内存管理代码规范:

1>只要调用了alloc,必须有release(autorelease

    对象不是通过alloc产生的,就不需要release

2>set方法的代码规范

① 基本数据类型:直接复制

1  - (void)setAge:(int)age
2  { 
3     _age = age;
4  }

② OC对象类型

 1 - (void)setCar:(Car *)car
 2  {
 3     // 1.先判断是不是新传进来对象
 4     if ( car != _car )
 5     {
 6         // 2.对旧对象做一次release
 7         [_car release];
 8  
 9         // 3.对新对象做一次retain
10         _car = [car retain];
11     }
12  }

3.dealloc方法的代码规范

 1> 一定要[super dealloc],而且放到最后面

 2> 对self(当前)所拥有的其他对象做一次release

1 - (void)dealloc
2  {
3     [_car release];
4     [super dealloc];
5  }

 

(三) @property参数

格式:@property(参数1,参数2)类型 名字; 
参数可有可无
参数主要分为3类
①读写属性:readwrite/readonly

*readwrite :同时生成set方法和get方法(默认)

*readonly  :只会生成get方法

②setter处理:assign/retain/copy

*retain : release旧值,retain新值(用于OC对象)
1 @property (retain) Book *book;

*assign : 直接赋值,不做任何内存管理(默认,用于非OC对象类型)

*copy   : release旧值,copy新值(一般用于NSString *)
③原子性:atomic/nonatomic
前者性能低和后者性能高,控制多线程管理
1 @property (getter = isRich) BOOL rich;
2 
3 @property (nonatomic, assign, readwrite) int weight;
4  
5 @property (readwrite, assign) int height;
6 
7 @property (nonatomic, assign) int age;
8 
9 @property (retain) NSString *name;
 
(四)循环引用
 1) @class的作用:仅仅告诉编译器,某个名称是一个类
      @class Person; // 仅仅告诉编译器,Person是一个类

 2)开发中引用一个类的规范

 1> 在.h文件中用@class来声明类

 2> 在.m文件中用#import来包含类的所有东西

 3)两端循环引用解决方案

 1> 一端用retain

 2> 一端用assign

1 #import <Foundation/Foundation.h>
2 #import "Card.h"
3 
4 @interface Person : NSObject
5 
6 @property (nonatomic, retain) Card *card;
7 
8 @end

(五) autorelease

1>autorelease的基本用法

           ①  会将对象放到一个自动释放池中

           ②  当自动释放池被销毁时,会对池子里面的所有对象做一次release操作

           ③  会返回对象本身

           ④  调用完autorelease方法后,对象的计数器不变 

2>autorelease的好处
           ①  不用再关心对象释放的时间
           ②  不用再关心什么时候调用release
 
3>autorelease的使用注意
           ①  占用内存较大的对象不要随便使用autorelease
           ②  占用内存较小的对象使用autorelease,没有太大影响
4>错误写法
           ①  alloc之后调用了autorelease,又调用release

 
 

posted on 2015-03-23 18:20  lijifeng  阅读(161)  评论(0编辑  收藏  举报