黑马程序员——OC语言 内存管理
(以下内容是对黑马苹果入学视频的个人知识点总结)
(一)计数器
每个对象内部都保存了一个与之相关联的整数,称为引用计数器,当使用alloc、new或者copy创建一个对象时,对象的引用计数器被设置为1
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参数
*readwrite :同时生成set方法和get方法(默认)
*readonly :只会生成get方法
②setter处理:assign/retain/copy
1 @property (retain) Book *book;
*assign : 直接赋值,不做任何内存管理(默认,用于非OC对象类型)
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;
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