黑马程序员——07-内存管理之一

一、引用计数器

每个OC对象都有自己的引用计数器,是一个整数,表示“对象被引用的次数”,每个OC对象内部有4个字节的存储空间存储引用计数器

1、作用

  • 当使用allocnewcopy创建一个新对象时,引用计数器的默认值为1
  • 当一个对象的引用计数器的值为0时,对象占用的内存就会被系统回收
  • 判断对象占用内存是否回收的唯一依据

2基本使用

 1> retain :计数器+1,会返回对象本身

 2> release :计数器-1,没有返回值,不代表释放对象

 3> retainCount :获取当前的计数器

3 内存回收

  •   当一个对象的引用计数器的值为0时,它将会被销毁,对象占用的内存被系统回收
  •   当一个对象被回收的时候,系统就会自动调用dealloc方法
  •   一般重写dealloc方法,释放相关资源
  •    重写dealloc方法,一定要调用[super dealloc],这句调用要放在最后面
  •   对象被回收,占用的内存就不可再用,否则会导致野指针错误

4、相关概念

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

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

空指针 :没有指向任何东西的指针(存储的东西是nilNULL0),给空指针发送消息不会 报错

5、重写dealloc方法简单示例

- (void)dealloc
{
    NSLog(@"Person对象被回收");
    [super dealloc];
}


二、内存管理原则

1、谁创建,谁release

如果你通过alloc、new、 copy来创建一个对象,那么你必须调用release或autorelease,

换句话说,不是你创建的,就不用你去[auto]release

2、谁retain,谁release

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

 

三、内存管理代码规范

1、原则

只要调用了alloc,必须有releaseautorelease),对象不是通过alloc产生的,就不需要release

 2set方法的代码规范

 (1) 基本数据类型

- (void)setAge:(int)age
 { 
    _age = age;
 }

(2) OC对象类型

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

3dealloc方法的代码规范

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

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

 - (void)dealloc
 {
    [_car release];
    [super dealloc];
 }

四、@property参数

1、使用@property参数原因

@property可以生产setget方法,但是生产的set方法仅仅是赋值,并没有进行内存管理

示例:

@property Book *book;
- (void)setBook:(Book *)book
{
_book = book; //仅是赋值操作
}

2、set方法内存管理相关的参数

  • retain : release旧值,retain新值(适用于OC对象类型)
  • assign : 直接赋值(默认,适用于非OC对象类型)
  • copy   : release旧值,copy新值

 示例:

@property (retain) Book *book;

生成的set方法里面,release旧值,retain新值

- (void)setBook:(Book *)book
{
    if (_book != book)
    {
        [_book release];
        
        _book = [book retain];
    }
}

 3.是否要生成set方法

  readwrite : 同时生成settergetter的声明、实现(默认)

  readonly  : 只会生成getter的声明、实现

 

 4.多线程管理

  nonatomic : 性能高 (一般就用这个)

  atomic    : 性能低(默认)

 示例:

@property (nonatomic, assign) int age;

 

 5.settergetter方法的名称

  setter : 决定了set方法的名称,一定要有个冒号 :

  getter : 决定了get方法的名称(一般用在BOOL类型)

示例:

@property (getter = isRich) BOOL rich;
//使用
Person *p = [[Person alloc] init];
p.rich = YES;
BOOL b = p.isRich;


 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值