黑马程序员——OC学习笔记05 内存管理1

本文深入探讨Objective-C中的内存管理机制,包括局部变量与对象的存储方式、对象计数器的工作原理、野指针与空指针的概念、多对象内存管理原则、@property属性的内存管理选项以及循环引用问题的解决办法。
摘要由CSDN通过智能技术生成

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


一、局部变量和指向对象的指针存放在栈中,它们是局部变量。程序会自动回收它们。对象存放在堆中,需要手动进行管理。


二、对象的计数器。

  • 对象的结构,每个对象都有自己的引用计数器,表示对象被引用的次数。
  • 每个对象都会特地分配4个字节的空间来存放引用计数器。
  • 当计数器为0时,对象将会被销毁,内存被回收。
  • 当使用allocnewcopy创建新对象的时候,对象的引用计数器为1
  • 当给对象发送retain消息的时候(调用对象retain方法),对象计数器 + 1
  • 当给对象发送release消息的时候,对象的计数器 - 1
  • 给对象发送一条retainCount方法,获取当前的引用计数器数值。

 

对象的销毁

  • 当一个对象的引用计数器为0时,他将被销毁,所占用的内存被系统回收。
  • 当一个对象销毁时,系统会自动向对象发送一条dealloc消息。
  • 一般会重写dealloc方法,在这里释放相关资源,dealloc就像对象的遗言。
  • 一旦重写了dealloc方法,就必须调用[super dealloc],并且放在最后面调用。
  • 千万不要直接调用dealloc方法

 

retain方法返回的是对象本身。

[p retain] == p;



三、野指针和空指针

僵尸对象:引用计数器被减为0的对象就是僵尸对象,当某个对象引用计数器为0的时候,指向它的指针还指向它。但是它已经不可用了。所以指向它的指针,变为了野指针。

野指针:指向僵尸对象(不可用的内存)的指针,就叫野指针。

操作野指针是一个危险的行为。

为了防止野指针:

  • 在对象计数器减为0之后,清空指针p = nil;给空指针发送消息不会报错。
  • OC里面没有空指针错误。JAVA里面有空指针错误。

四、多对象内存管理

多个对象内存管理原则:

  • 你像要使用某个对象,你就给他+1
  • 你不想要某个对象,就给他 - 1
  • 有加就有减
  • 如果对象不是通过alloc产生的,就不许产生对应的release。比如NSString

多对象内存管理主要涉及到set方法和循环引用问题。
手动内存管理中的set方法
<span style="font-family:SimHei;font-size:18px;">- (void)setCar:(Car *)car
{
    if (_car != car) {
        [_car release];
        _car = [car retain];
    }
}
</span>
先判断旧的成员变量和新的是否一样,如果一样,不做任何操作,如果不一样,则把旧的release掉,新的retain,然后在赋值。

五、@property内存管理

之前的 @propertyBook *book;它自动生成的set方法是没有内存管理功能的。

 

当在@property(retain) Book *book; 加上(retain)就会在set方法中生成内存管理代码。

 

retain代表了生成了set方法里面release旧值,retain新值。

 

最后别忘了在deallocrelease对象成员变量。

 

注意,基本数据类型不能添加(retain)

 

1@property内存管理相关的参数(三选一,只能写一个)

  • retain : release旧值,retain新值(适用于OC对象)
  • assign: 直接赋值(默认的,基本数据类型用这种,写不写都行。)
  • copy : release旧值, copy新值

 

2、是否要生成set方法(二选一,只能写一个)

  • readonly : 只读,不生成set方法,只生成get方法的声明和实现。
  • readwrite : 可读可写(默认)

 

3、多线程管理

  • nonatomic : 告诉系统,生成set方法的时候不要生成多线程代码(性能高)(建议必写)
  • atomic : (性能低)(默认)

 

4settergetter方法的名称

  • getter = 新的方法名(一般用来修改BOOL
  • setter = 新的方法名:(注意后面的冒号)
  • 这两个不冲突,可以写在一起。


六、循环引用。

1、@class 类名仅仅是告诉编译器 card是一个类。

 

两个相互引用的对象,不能都用 #import 互相引用.h文件,这里用class

 

用了@class后,.m文件要#import 要包含的文件的.h文件。

 

规范

  • 在头文件中使用@class
  • .m文件中用#import包含.h文件。

2、循环引用的内存管理

两个对象循环引用两端都用retain会导致对象都无法被销毁。

解决方案:两端循环引用的解决方案:

  • 一端用retain
  • 一端用assign(用assign别忘了不要dealloc方法中release

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值