OC学习笔记七---内存管理一
2015-01-28 10:43
99 查看
一、为什么要内存管理
移动设备的内存极其有限,每个app所能占用的内存是有限制的,如果app占用过多内存,应用程序也会不能继续运行。如果内存管理不当,也会出现空指针,野指针,僵尸对象等错误。在OC中,如果没有开启ARC,对任何继承了NSObject的对象,都要进行内存管理。系统会对其他基本数据类型(int、char、float、double、struct、enum等)自动进行内存管理。二、内存管理的原理
在每个对象内部,都有一个4个字节的引用计数器,表示“对象的引用个数”,当时用new,alloc,copy创建一个新对象后,计数器的值为1。当对象调用retain方法时,计数器加1,当调用release方法是,计数器减1。学过操作系统的人应该会知道,这两个方法和操作系统进程管理的PV操作很像,有可能发明OC语言的人写内存管理是借鉴操作系统中的进程管理呢,呵呵。当计数器的值减为0后,对象会被回收。在对象被销毁之前,系统会想对象发送一条dealloc消息。三、关闭ARC
ARC(Autom Reference Counting)是IOS5的新功能,会自动帮我们实现对象的内存管理,并且不能调用手动管理内存的方法。为了学习内存管理,我们必须关闭ARC,手动实现内存管理。点击工程->build setting->all,在搜索框中输入auto,找到Object-C Automatic Reference Counting,把YES改成NO,就关闭了这个项目的ARC功能。
四、内存管理的原则
1. 谁创建,谁release
如果你通过alloc、new或[mutable]copy来创建一个对象,那么你必须调用release或autorelease2. 谁retain,谁release
只要你调用了retain,无论这个对象是如何生成的,你都要调用release五、多对象内存管理
新建一个控制台工程,在工程中添加Person类和 book类
book
h
#import <Foundation/Foundation.h> @interface<a target=_blank class="izllvbhl" href="#" title="Click to Continue > by MacVx"> book<img src="http://cdncache-a.akamaihd.net/items/it/img/arrow-10x10.png" alt="" /></a> : NSObject { int _price; } - (void)setPrice:(int)price; - (int)price; @end
book
m
#import <a target=_blank class="izllvbhl" href="#" title="Click to Continue > by MacVx"> book<img src="http://cdncache-a.akamaihd.net/items/it/img/arrow-10x10.png" alt="" /></a>.h" @implementation Book - (void)setPrice:(int)price { _price = price; } - (int)price { return _price; } -(void)dealloc { NSLog(@"Book对象被回收!"); [super dealloc]; } @end
Person.h
#import <Foundation/Foundation.h> #import <a target=_blank class="izllvbhl" href="#" title="Click to Continue > by MacVx"> book<img src="http://cdncache-a.akamaihd.net/items/it/img/arrow-10x10.png" alt="" /></a>.h" @interface Person : NSObject { <a target=_blank class="izllvbhl" href="#" title="Click to Continue > by MacVx"> book<img src="http://cdncache-a.akamaihd.net/items/it/img/arrow-10x10.png" alt="" /></a> *<a target=_blank class="izllvbhl" href="#" title="Click to Continue > by MacVx"> book<img src="http://cdncache-a.akamaihd.net/items/it/img/arrow-10x10.png" alt="" /></a>; } - (void)setBook:<a target=_blank class="izllvbhl" href="#" title="Click to Continue > by MacVx"> book<img src="http://cdncache-a.akamaihd.net/items/it/img/arrow-10x10.png" alt="" /></a> *<a target=_blank class="izllvbhl" href="#" title="Click to Continue > by MacVx"> book<img src="http://cdncache-a.akamaihd.net/items/it/img/arrow-10x10.png" alt="" /></a>; - (Book *)book; @end
Person.m
#import "Person.h" @implementation Person - (void)setBook:(Book *)book { _book = book; } - (Book *)book { return _book; } -(void)dealloc { NSLog(@"Person对象被回收!"); [super dealloc]; } @end
在main函数中创建Person对象和Book对象,现在想让Person对象拥有Book对象,依照我们刚才说的原则,代码很容易写。
#import <Foundation/Foundation.h> #import "Book.h" #import "Person.h" int main(int argc, const char * argv[]) { Book *b = [[Book alloc] init]; Person *p = [[Person alloc] init]; p.book = b; [p release]; [b release]; return 0; }
运行结果好像也没问题。
但是,如果我们将最后的两个release调换位置,仔细分析一下会发现当先运行了[b realease]后,Book对象就被销毁了,但是p对Book对象还有一个引用,这样是不合理的!
分析后发现,在p.book = b; 我们并没有让b的引用计数器加1。所以,在Person的set方法中,将_book = book;改成_book = [book retain];把retain之后的返回的book对象赋值给_book。
运行程序
只有Person对象被回收了!
回想内存管理的原则,有了retain就必须有release,但是我们在set方法中retain之后没有realease。所以,还要在Person的dealloc方法中加入[_book realase];程序才能运行成功。
相关文章推荐
- C++内存管理
- 《iOS总结》OC内存管理-MickyChiang
- python的内存管理机制
- [转] 栈的内存管理
- 手动内存管理和自动释放池
- JVM-内存管理及创建对象
- iOS 内存管理
- JavaScript内存管理介绍
- 《Objective-C高级编程:iOS与OS X多线程和内存管理》读后感
- Linux内存管理(上)
- 十一、内存管理中的循环引用
- Thinking in java-4 Java内存管理之垃圾回收Garbage Collection
- Objective-C 日记⑤ 内存管理、协议、Category 视频笔记
- Unity开发者的C#内存管理(中篇)
- linux内核之内存管理图解
- window中内存管理学习
- linux kernel学习笔记- 内存管理
- 内存管理
- linux内存管理浅析
- 内存管理 三