iOS开发之OC语法基础(四)--内存管理
来源:互联网 发布:ajax获取前台数据 编辑:程序博客网 时间:2024/05/24 01:04
一、课程目标:
1、掌握内存管理的原则
2、深入理解属性的内存管理
3、掌握便利构造器内存管理
4、掌握NSAutoreleasePool(自动释放池)的使用
二、如何管理内存?
1、解决办法:
有创建,就要有销毁
所谓 内存管理:针对创建和销毁过程进行管理
2、管理方式:
垃圾回收(java、C#等)
人工管理(OC、C、C++)
自动管理内存(ARC、IOS5新特性),并非垃圾回收
3、引用计数:
OC采用“引用计数机制”(retainCount)管理对象所占用的内存
计数:计数器,用于统计数字。例如:1、2、3...等
引用计数:某一块内存,拥有这块内存的拥有着的个数。
注意:在OC语言中,NSObject类以及子类的实例对象包含一个整型属性,用来统计当前的引用计数
4、生命周期
实例对象的生命周期
出生于alloc方法
死亡于dealloc方法
注意:通过对类发送alloc消息,获得的实例对象的引用计数赋值为1!
注意:当实例对象的引用计数为0时,自动对该实例对象发送dealloc消息!
5、常见方法
copy制造一个副本,将副本的引用计数赋值为1,拥有副本的所有权。
retain对象引用计数+1,并拥有对象所有权。
release对象引用计数-1,并放弃对象所有权。
autorelease未来某个时间对象引用计数-1,并放弃对象所有权。
引用计数的变化
Student * stu = [[Student]init];NSLog(@“创建时计数为:%lu”,[stu retainCount]);[stu retain];//调用了retain方法,计数器应该加1NSLog(@“retain后计数为:%lu”,[stu retainCount]);[stu release];//计数器减一[stu release];//计数器再减一
6、指针变量与对象
对象是放在堆里的
指针变量时放在栈里的
唯一的联系:指针变量存的是对象的地址
7、对象的实例属性
@property Student * stu;
//设置器- (void)setStu:(Student *)stu{<span style="white-space:pre"></span>_stu = stu;}//访问器- (Student)stu{<span style="white-space:pre"></span>return _stu;}
代码执行步骤:
然后执行:[student release];
然后执行:[mc.stu sayHi];
注意:地址为0x10ff78c的student对象已经被销毁,无法接收sayHi消息,程序崩溃!
为了解决崩溃:
@property(retain,nonatomic) Student * stu;
//设置器- (void)setStu:(Student *)stu{<span style="white-space:pre"></span>[stu retain];<span style="white-space:pre"></span>[_stu release];_stu = stu;}//访问器- (Student)stu{return _stu;}代码执行步骤:
注意:地址为0x10ff78c的student对象没有被销毁,可以接收sayHi消息,程序正常!
dealloc方法在对象引用计数为0的时候自动调用
主要用于释放自身所占有的资源,永远不要手动调用dealloc。
8、便利构造器内存管理
阅读下面代码,看内存是否有问题
+ (id)studentWithName:(NSString *)name andAge:(NSInteger)age andHobby:(NSString *)hobby andAddress:(<span style="font-family: Arial, Helvetica, sans-serif;">NSString *</span>)address{ Student *student = [[Student alloc]initWithName:name andAge:age andHobby:hobby andAddress:address]; [student release]; return student;}注意:地址为0x10ff78c的student对象已经被销毁,虽然将地址返回,但已经不能接受消息!!!
那么便利构造器要怎么进行内存管理呢,我们需要用到自动释放池
自动释放池:
NSAutoreleasePool类
当创建的对象未来某个时候销毁时,可以使用对象的autorelease方法
对象将所有权交给最近的NSAutoreleasePool对象
当池对象drain或release时,会逐一对池内对象发送release消息
尽量不要使用autorelease,而是使用release
便利构造器
+ (id)studentWithName:(NSString *)name andAge:(NSInteger)age andHobby:(NSString *)hobby andAddress:(NSString *)address{ Student *student = [[Student alloc]initWithName:name andAge:age andHobby:hobby andAddress:address]; return [student autorelease];//不立即释放,而是交给autoreleasepool}自动释放池
//较早版本的创建NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];<pre name="code" class="objc">Student * stu = [[Student alloc]init];//alloc一个对象[stu autorelease];// 将所有权控制交给pool,stu不用手动release了...[pool release];
//现版本的创建@autoreleasepool{ Student * stu = [[Student alloc]init];//alloc一个对象 [stu autorelease];// 将所有权控制交给pool,stu不用手动release了 ...}
示例1:
+ (id)personWithName:(NSString *)aName{Person * person = [[Person alloc]initWithName:aName];return [person autorelease];}示例:
- (void)printName{NSString *name = @"hello";NSLog(@"%@",name);}
- (void)printHello{NSString *str = [NSString stringWithFormat:@"Hello"];NSLog(@"%@",str);}9、内存检测工具
Analyze内存静态分析(编译期)
leaks内存泄露检测工具(运行期)
三、总结
内存管理原理:
凡是alloc、retain、copy的地方,都应出现release或autorelease与之对应
属性为retain或copy的话,需要在类的dealloc中释放这个属性
便利构造器本身应包含autorelease
一定不要释放没有所有权的对象。不要手动调用dealloc
四、术语与技巧
ios程序开发离不开内存管理。虽然原则很简单,但是真正做好内存管理还是比较困难的。
法宝:只要自己使用了alloc、retain、copy,就一定要有对应的release、autorelease,它们要配对使用。
工具:Analyze和Instruments(leaks)
必杀技:dealloc中打印NSLog,看dealloc是否执行
- iOS开发之OC语法基础(四)--内存管理
- iOS编程基础-OC(四)-内存管理(续)
- iOS编程基础-OC(四)-内存管理
- 【OC语法快览】四、基础内存管理
- iOS开发之OC语法基础(五)--字符串
- iOS开发之OC语法基础(六)--可见度
- iOS开发之OC语法基础(七)--集合
- iOS开发之OC内存管理
- iOS开发之OC内存管理(一)
- iOS开发之OC内存管理(二)
- 黑马程序员-iOS基础-Objective-C基础(四)OC开发技巧及核心语法(上)
- 黑马程序员——ios开发基础之OC内存管理与blocks
- iOS 之OC内存管理(一)
- iOS 之OC内存管理(二)
- iOS开发之OC语法基础(三)--属性、点语法
- OC的手动内存管理基础(IOS开发)
- 黑马程序员—IOS基础之OC—内存管理
- 黑马程序员-IOS基础之OC内存管理
- USACO 2.2.3 货币系统
- hdoj problem 1241 Oil Deposits(深搜 DFS)
- Git-08_冲突
- OpenCV2计算机视觉应用编程手册(自学版)初级五
- Struts2漏洞分析与研究之Ognl机制探讨
- iOS开发之OC语法基础(四)--内存管理
- 以结点p为根的子树中序线索化
- 人品计算器1.0版本
- 带头结点的中序线索化
- 菜鸟授徒系列之新手入门
- 遍历中序线索二叉树
- USACO 2.2.4 两只塔沃斯母牛
- liferay namespace用法
- 构造赫夫曼树