您当前位置:首页 > 睿峰资讯 > 技术论坛 > 技术课堂|iOS内存管理

技术课堂|iOS内存管理

时间:2016-10-28 09:01:31   来源:未知  作者:睿峰

目录:
1.内存管理介绍
2.引用计数
3.内存管理原则
4.引用计数
5.自动释放池
6.便利构造器
7.正确编写对象类型的设置器

一丶内存管理原则

1.什么是内存管理


内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。

2.为什么要进行内存管理

程序运行时,内存资源是有限的,Objective-C编写程序过程中创建实例化对象会占用内存,程序使用的内存会随着程序中对象的增加而不断增加,久而久之,最终系统资源被消耗殆尽。
Mac OS 有垃圾回收机制,但iOS没有,iOS内存远不足于Mac OS系统,iOS将内存管理的任务交给了开发者。

二丶引用计数

1.引用计数介绍

Cocoa采用引用计数的技术来确定对象的生命周期结束。
在引用计数中,每一个对象负责维护对象所有引用的计数值。当一个新的引用指向对象时,引用计数器就递增,当去掉一个引用时,引用计数就递减。当引用计数到零时,该对象就将释放占有的资源。


  • Cocoa为每个对象设定了一个引用计数,retainCount
  • 当对象被创建时,引用计数置为1(alloc、copy或则new);
  • 使对象的引用计数+1,并且获得对象的所有权;
  • 使对象的引用计数-1,并且放弃对象的所有权;
  • 当引用计数值为0的时候,对象将被系统销毁。


eg:
Person* person=[[Person alloc] init]; //计数器为1
[person retain];//计数器为2
NSLog(@“%ld”,[personretainCount]);
[person retain];//计数器为3
[personrelease]; //计数器减1,变为2
[personrelease]; //计数器减1,变为1
NSLog(@“%ld”,[personretainCount]);
[person retain];//计数器加1,变为2
[personrelease]; //计数器减1,变为1
[personrelease];
NSLog(@“%ld”,[personretainCount]);
//计数器减1,变为0,但不会直接打印输出为0
//然后系统调用dealloc方法将person指向的内存销毁

2. 内存管理的基本方法

  • retainCount:获取对象当前的引用计数值;
  • alloc:返回一个对象,并将其引用计数设置为1,类方法;
  • retain:将对象的引用计数加1;
  • release:将对象的引用计数减1;
  • autorelease:将对象加入自动释放池,对象引用计数滞后减1;
  • 除了上述方法之外,还有对象销毁的方法dealloc,我们不会主动调用,但是需要在类中重写;

三丶内存管理的基本原则
  • 任意对象在使用前必须alloc
  • 每一个alloc,必须对应一个release或者autorelease
  • 每一个retain,必须对应一个release或者autorelease
  • 不能使用引用计数为0的对象
  • 每一个对象在使用完毕后必须销毁
  • 尽量保证在使用完毕后立即销毁对象
  • 常量的引用计数为正无穷(即所有常量不需要管理内存)


eg1:
Person *person =[[Person alloc] initWithName:@“张三” ];
NSLog(@”%@”,person.name);
[person release];//不适用person对象后,将其释放

eg2:
Person *person =[[Person alloc] initWithName:@“张三” ];
NSString *name =person.name;
NSLog(@”%@”,person.name);
[personrelease];//不使用person对象后,将其释放,而name不能释放,因为name是我们间接获得的,我们没有它的所有权,不能对它进行释放。

四丶内存管理原则

  • 任意对象在使用前必须alloc
  • 每一个alloc,必须对应一个release或者autorelease
  • 每一个retain,必须对应一个release或者autorelease
  • 不能使用引用计数为0的对象
  • 每一个对象在使用完毕后必须销毁
  • 尽量保证在使用完毕后立即销毁对象
  • 常量的引用计数为正无穷(即所有常量不需要管理内存)

五丶自动释放池
  • NSAutoreleasePool自动释放池类似于一个容器,所有放入容器中的对象将被池管理内存;
  • 使用NSObject类的对象方法autorelease将对象加入池中,被加入池中的对象将在池自身释放时被统一释放一次(retaincount减1);
  • 初始化NSAutoreleasePool:
  • 主线程中系统为我们创建的自动释放池,无需手动新建;子线程中需要手动创建自动释放池,并释放销毁池。

eg:
//初始化自动释放池
NSAutoreleasePool*pool = [[NSAutoreleasePool alloc] init];
//add object into autorelease pool…
// 池释放销毁,池中所有对象被release一次
[pool release];

六、便利构造器

有时我们会通过便利构造器来获得一个新的对象,由便利构造器产生的对象不应当由使用者销毁,而是由便利构造器本身完成。便利构造器通过在实现中调用autorelease,来实现上述功能

  • 使用便利构造器创建对象,则使用完毕后不需要进行释放
  • - (void)printHello
  • {
  • NSString *string =[NSString stringWithFormat:@"Hello"];
  • NSLog(@"%@",string);
  • 便利构造是在构建对象的同时直接添加释放操作:
  • NSMutableArray *array = [NSMutableArray array];
  • 便利构造方法就等于alloc的同时 autorelease ,上面的语句等于:
  • NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease];

七丶正确编写对象类型的设置器

在设置器中,保持对新传入对象的所有权,同时放弃旧对象的所有权

eg:
@interface Person : NSObject
{
NSString *_name;//姓名
}
@end


@implementation Person
-         (void)setName :(NSString*)aName
{
if(_name = aName){
[_name release];
_name = [aNameretain];
}
}

-         (NSString *)name{
return name;
}
@end


或则:
- (void) setName : (NSString*) name{
[name retain];
[_name release];
_name= name;
}
上一篇:收藏|让你强大的62种免费工作资源!  
下一篇:技术课堂|自定义转场动画

睿峰教育——做受尊敬的培训机构 价值观: 敬畏 感恩 责任 创新 使命——通过移动互联产品提升人类生活品质 join us