黑马程序员----oc加强笔记----内存管理
来源:互联网 发布:ug8.0编程在线视频观看 编辑:程序博客网 时间:2024/05/21 06:56
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1、内存管理基本概念
为什么要进行内存管理?
由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时,系统就会发出内存警告,个app可用的内存是被限制的,如果一个app使用的内存超过20M,则系统会向该app发送Memory Warning消息。收到此消息后,需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量等,否则程序会崩溃。
内存管理范围:
管理任何继承NSObject的对象,对其他的基本数据类型无效
本质原因是因为对象和其他数据类型在系统中的存储空间不一样,其它局部变量主要存放于栈中,而对象存储于堆中,当代码块结束时这个代码块中涉及的所有局部变量会被回收,指向对象的指针也被回收,此时对象已经没有指针指向,但依然存在于内存中,造成内存泄露。
2、内存管理的原理
1)对象的所有权及引用计数
所有权概念:
任何对象都可能拥有一个或多个所有者。只要一个对象至少还拥有一个所有者,它就会继续存在
引用计数器:
每个OC对象都有自己的引用计数器,是一个整数表示对象被引用的次数,即现在有多少东西在使用这个对象。对象刚被创建时,默认计数器值为1,当计数器的值变为0时,则对象销毁。
2)对引用计数器的操作
给对象发送消息,进行相应的计数器操作。retain消息:使计数器+1,该方法返回对象本身release消息:使计数器-1(并不代表释放对象)retainCount消息:获得对象当前的引用计数器值
3)对象的销毁
当一个对象的引用计数器为0时,那么它将被销毁,其占用的内存被系统回收。当对象被销毁时,系统会自动向对象发送一条dealloc消息,一般会重写dealloc方法,在这里释放相关的资源,dealloc就像是对象的“临终遗言”。一旦重写了dealloc方法就必须调用[super dealloc],并且放在代码块的最后调用(不能直接调用dealloc方法)。一旦对象被回收了,那么他所占据的存储空间就不再可用,坚持使用会导致程序崩溃(野指针错误)。
注意;
1) 如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收(除非整个程序已经退出)
分区 第一天(@传智如意大师) 的第10页
非整个程序已经退出 )
2)任何一个对象,刚生下来的时候,引用计数器都为1。(对象一旦创建好,默认引用计数器就是3)当使用alloc、new或者copy创建一个对象时,对象的引用计数器默认就是1
3、内存管理分类:
1)MRC 手动内存管理
2)ARC 自动内存管理
4、手动内存管理入门
代码及理解:
Person类的创建,声明部分:
#import <Foundation/Foundation.h>@interface Person : NSObject@end
Person类的实现部分:
#import "Person.h"@implementation Person//dealloc方法,是对象的临终遗言的方法//对象被销毁的时候,会默认的调用该方法//注意:dealloc 方法是系统根据引用计数器的值,自动调用的,//不需要手动调用- (void)dealloc{ //1 先释放子类自己的对象的空间 NSLog(@"Person已经挂了"); //2 再释放父类的 [super dealloc];}@end主程序:
#import <Foundation/Foundation.h>#import "Person.h"int main(int argc, const char * argv[]) { @autoreleasepool { //用Person 类实例化一个实例对象 Person *p = [Person new]; // 对象有没有所有者? 有// [p dealloc]; //证明有一个所有者 NSUInteger count = [p retainCount]; NSLog(@"count = %lu",count); // 1 //使用引用计数器+1// Person *p2 = p; // //Person *p2 = [p retain]; [p retain]; NSLog(@"p.retainCount = %lu",[p retainCount]); //2 //如果要回收对象? 应该想办法 retatinCount = 0 [p release]; NSLog(@"p.retainCount = %lu",[p retainCount]); //1 [p release]; //此处执行后,p的空间被回收 //0 //证明p的空间被释放了,可以在在Person类中,重写dealloc方法 } return 0;}5、内存管理的原则
1)原则
只要还有人在使用某个对象,那么这个对象就不会被回收;只要你想使用这个对象,那么就应该让这个对象的引用计数器+1;当你不想使用这个对象时,应该让对象的引用计数器-1;
2)谁创建,谁release
(1)如果你通过alloc,new,copy来创建了一个对象,那么你就必须调用release或者autorelease方法
(2)不是你创建的就不用你去负责
3)谁retain,谁release
只要你调用了retain,无论这个对象时如何生成的,你都要调用release
4)总结
有始有终,有加就应该有减。曾经让某个对象计数器加1,就应该让其在最后-1.
6、单个对象内存管理(野指针问题)
代码及理解:
创建一个狗的类,声明部分:
#import <Foundation/Foundation.h>@interface Dog : NSObject{ @public int _a;}-(void)eat;@end狗类的实现部分:
#import "Dog.h"@implementation Dog-(void)eat{ NSLog(@"狗正在吃一坨粑粑");}- (void)dealloc{ NSLog(@"狗已经挂了"); [super dealloc];}@end主代码及理解注释:
#import <Foundation/Foundation.h>#import "Dog.h"int main(int argc, const char * argv[]) { @autoreleasepool { //创建一个对象 //对象创建完成以后,默认的所有者有一个,是自己,所以引用计数为1 Dog *byd = [Dog new]; //1 [byd eat]; // NSLog(@"byd.retainCount = %lu",byd.retainCount); //如果一个对象已经被释放了,这个对象就称之为僵尸对象 // [byd release]; //0// NSLog(@"byd.retainCount = %lu",byd.retainCount); //值已经没有意义了 //这句话默认情况下不报错, //如果要让他报错,要开启僵尸对象检测 //byd指针也就是野指针// [byd eat]; //野指针访问 // [byd retain]; //byd 已经是僵尸对象了,不能复生 } return 0;}7、单对象内存管理(内存泄露问题)
代码及理解注释:
创建一个狗的类:
#import <Foundation/Foundation.h>@interface Dog : NSObject-(void)eat;-(BOOL)compareColorWithOther:(Dog*)dog;@end
#import "Dog.h"@implementation Dog-(BOOL)compareColorWithOther:(Dog*)dog{ [dog retain]; //让传入的对象的引用+1 return YES;}-(void)eat{ NSLog(@"狗在吃");}- (void)dealloc{ NSLog(@"狗已经挂了"); [super dealloc];}@end类存泄露情况总结:
int main(int argc, const char * argv[]) { @autoreleasepool { //单个对象的内存泄露问题 //内存泄露情况1: // 创建完成 使用之后,没有release// Dog *d = [[Dog alloc] init]; //1// NSLog(@"%lu",d.retainCount); //使用d对象 //内存泄露情况2: //没有遵守内存管理的原则// Dog *d = [[Dog alloc] init]; //1// [d retain]; //2//// [d release];// [d release]; //1 //内存泄露的情况3: //不当的使用了nil// Dog *d = [[Dog alloc] init]; //1// d = nil;// // [d eat]; //nil eat// [d release]; // nil release //内存泄露的情况4: //在方法中对传入的对象进行了retain Dog *d = [[Dog alloc] init]; //1 NSLog(@"d.retainCount = %lu",d.retainCount); //对象依然被泄露了 [d compareColorWithOther:d]; //2 NSLog(@"d.retainCount = %lu",d.retainCount); [d release]; } return 0;}
- 黑马程序员----oc加强笔记----内存管理
- 黑马程序员--学习OC加强内存管理
- 黑马程序员-OC加强回顾-内存管理
- 黑马程序员-OC加强-内存管理
- 黑马程序员—IOS加强视频—oc内存管理
- 黑马程序员——oc加强学习(内存管理)
- 黑马程序员-OC学习笔记-----内存管理
- 黑马程序员-OC的内存管理笔记
- 黑马程序员----oc加强笔记----分类(Gategory)
- 黑马程序员----oc加强笔记----Foundation\NSString
- 黑马程序员----oc加强笔记----block
- 黑马程序员-OC-内存管理
- 黑马程序员--oc:内存管理
- [黑马程序员][OC]内存管理
- 黑马程序员-OC内存管理
- 黑马程序员---OC--内存管理
- 黑马程序员---oc 内存管理
- 黑马程序员-OC-内存管理
- MySQL中不能插入中文解决办法
- Html入门学习总结
- Android Layout布局及属性
- Linux程序设计(curses使用示例)
- spring4泛型注入
- 黑马程序员----oc加强笔记----内存管理
- 稀疏编码自编码表达
- C/C++ struct/class/union内存对齐 [转]
- M进制字符串转为N进制字符串
- 新浪云sae部署yii2.0.6项目
- hdu1070
- UVA10305拓扑排序
- hdu 4308 Saving Princess claire_
- 数据库设计之概念、逻辑、物理模型