Objective-C知识总结

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

手动内存管理MRC

首先介绍一下引用计数器:用来保存当前对象有几个东西在使用它(数字)

引用计数器的作用:用来判断对象是否应该回收内存空间(如果对象不等于nil,当引用计数器为0,此时要回收对象的内存空间)

引用计数器的操作:

retain 使得引用计数器+1

release 使的引用计数器-1

retainCount 得到引用计数器的值

如果一个对象被释放的时候,会调用该对象的dealloc方法

注意:

dealloc方法是NSObject 的,一般我们要重写dealloc方法在dealloc 方法的内部,要调用 [super dealloc];内存管理的范围:

所有的集成了NSObject的对象的内存管理

基本数据类型(int double float char struct enum )的数据内存不需要我们进行管理

内存管理的原则:

如果对象有人使用,就不应该回收

如果你想使用这个对象,应该让这个对象 retain一次

如果你不想使用这个对象了,应该让这个对象 relase一次

谁创建 谁release

谁 retain 谁 release

内存管理研究的内容:

野指针: 1)定义的指针变量没有初始化 2)指向的空间已经被释放

内存泄露:

{

Person*p = [Personnew];

}/*p 栈区

[Person new]; 堆区

如果栈区的p已经释放了,而堆区的空间还没有释放,堆区的空间就被泄露了*/

set方法内存管理

//Dog* _dog;//对于对象作为另外一个类的实例变量- (void)setDog:(Dog*)dog {//判断对象是否是原对象if(_dog !=dog) {//2) release旧值[_dog release];//retain 新的值,并且赋值给实例变量_dog =[dog retain];

}

}

循环retain问题

循环的retain 会导致两个对象都会内存泄露

防止方法:

让某个对象多释放一次 (注意顺序)

一端使用 assign 一端使用retain(推荐使用)

NSString类的内存管理问题

#import<Foundation/Foundation.h>intmain(intargc,constchar*argv[]) {

@autoreleasepool {//定义字符串//字符串的常量池,//如果你需要的字符串在常量池中已经存在了,不会分配内存空间//使用字符串的时候,//@"abc" stringWithString alloc initWithString 都在常量区/\//0x100001030 小NSString *str1 =@"abc";//@"abc" 字符串的常量NSString *str3 = [NSString stringWithString:@"abc"];//常量区NSString *str5 = [[NSString alloc] initWithString:@"abc"];//也在常量区NSString *str6 = [[NSString alloc] init];//常量区str6 =@"abc";//0x100202030 大//如果在常量区 str2 str4 地址应该是一样的//实际上不一样的,所以 str2 str4都在堆区NSString *str2 = [NSString stringWithFormat:@"abc"];//不是在栈区,在堆区NSString *str4 = [[NSString alloc] initWithFormat:@"abc"];//不是在栈区,在堆区//0x7fff5fbff764inta =10;//栈区NSLog(@"str1 = %@,%p,%lu",str1,str1,str1.retainCount);

NSLog(@"str2 = %@,%p,%lu",str2,str2,str2.retainCount);

NSLog(@"str3 = %@,%p,%lu",str3,str3,str3.retainCount);

NSLog(@"str4 = %@,%p,%lu",str4,str4,str4.retainCount);

NSLog(@"str5 = %@,%p,%lu",str5,str5,str5.retainCount);

NSLog(@"str6 = %@,%p,%lu",str6,str6,str6.retainCount);

NSLog(@"a = %p",&a);

}return0;

}

自动释放池 :特殊的栈结构

特点:

对象可以加入到自动释放池中自动释放池结束的时候,会给池中的对象发送一条 release消息自动释放池的使用:

创建自动释放池@autoreleasepool {

}

2. 加入自动释放池

/*在自动释放池中

[对象 autorelease];*/

模拟一个Person类 类中有个一个对象方法- (void)run;

#import<Foundation/Foundation.h>#import"Person.h"intmain(intargc,constchar*argv[]) {//1 创建自动释放池Person *p = [Personnew];//p 1@autoreleasepool {//自动释放池开始[p run];

NSLog(@"%lu",p.retainCount);//1//[p autorelease] 把对象p加入到自动释放池中//注意:加入到自动释放池中以后, 引用计数不会变化[p autorelease];//加入自动释放池,NSLog(@"%lu",p.retainCount);//1[p run];

}//自动释放池结束 [p release];[p run];return0;

}

我们可以给Person添加一个类方法,让其创建完对象就加入到自动释放池中

+(instancetype)person{//Person person ---> Person//Stduent person ----> Student//创建对象return[[[self alloc] init] autorelease];//返回的时对象的空间//能够帮我们把对象给加入到自动释放池}

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航