OC的内存管理机制

1. 为什么要使用内存管理

iOS应用程序出现crash(闪退), 90%以上的原因是出现了内存问题!
内存问题主要出现在内存溢出和野指针异常!

内存溢出 iOS给每个应用提供了一定的内存, 用于程序的运行, 一旦超过内存的上限,就会Crash,
野指针异常 对象内存空间已经被系统回收, 然而去还用指针指使用了这块内存!

2. 内存管理的分类

垃圾回收机制(gc);
垃圾回收机制: 程序员只需要开辟内存空间, 不需要用代码去释放! 系统自己来判断那些空间不再被使用, 并且回收这些内存空间以便再次分配, 整个回收的过程不需要写任何代码, 有系统自动完成垃圾回收, java开发中一直使用的就是垃圾回收机制!

MRC(Manual Reference Count) ; 人工引用计数;
人工引用计数: 内存的开辟和释放都是由程序代码进行控制, 相对于垃圾回收机制来说,对内存的控制更加灵活, 可以在需要释放的饿时候及时释放, 对程序员的要求较高, 程序员要熟悉内存的管理的机制!

ARM (Auto Reference Count);
自动引用计数:iOS 5.0的编译器特性, 它允许用户开辟空间, 不用去释放空间, 它不是垃圾回收! 她的本质还是MRC, 只是编译器帮程序员默认加了释放的代码,
iOS 支持MRC和ARC

3. 引用计数

C语言中,使用malloc 和 free 进行堆内存, 进行堆内存的创建和释放, 对内存只有正在使用和销毁两种状态!
实际开发中, 可能遇到两个以上的指针使用同一块内存, C语言无法记录内存使用个数!
OC采用引用计数管理内存, 当一个新的引用指向对象的时候, 引用计数器就递增, 当去掉一个引用时, 引用计数就递减, 当引用计数, 到零的时候, 该对象就是占有的资源!

OC引用技术的方法
  • alloc 引用计数+1;
    Person *p = [[Person alloc] init];
    // 显示引用计数
    NSLog(@"%ld", [p retainCount]); // 引用计数 1

  • retain 引用计数+1
    [p retain];
    NSLog(@"%lu", [p retainCount]); // 引用计数 2;

  • release 引用计数 -1
    [p release];
    NSLog(@"%lu", [p retainCount]); 引用计数 1;

但是, 当p再次release一次的时候,
[p release] // -1 此时p的引用计数为0, 因而对象应该是已被释放的!
NSLog(@"%lu", [p retainCount]); 打印却为1;
打出的引用计数虽然为1, 但他的实际为零, 对象已经被释放的!

  • autorelease autorelease引用计数不是立即 -1, 在未来的某一时刻(出了 autoreleasepool(自动释放池)) 之后, 引用计数再 -1**

通过autoreleasepool控制autorelease对象的释放!
向一个对象发送autorelease消息, 这个对象何时释放, 取决于autoreleasepool(自动释放池子)!

  Person *p2 = [[Person alloc] init]; 
  @autoreleasepool {
  [p2 retain]; 引用计数+1 为2;
  [p2 autorelease]; 此时引用计数为2;
  NSLog(@"%lu", [p2 retainCount]);
  }

NSLog(@"%lu", [p2 retainCount]); // 出了释放池, 计数 -1

  • copy 引用几计数 +1
    对象想使用copy, 必须签订copy协议, 实现copy协议
    person类签订copy协议, 实现copy方法

如下.h 和 .m 文件
Person .h 文件
// 签订copy协议
#import
@interface Person : NSObject <NSCopying>
@property(nonatomic, assign)NSString *name;
@property(nonatomic, assign)NSString *age
@end

Person  .m文件  // 必须重写delloc方法, 因为
  #import "Person.h"
  @implementation Person
  // 重写alloc方法
  - (void)dealloc
  {
  NSLog(@"******"); // 定义一个, 用于标记
  [super dealloc];
   }
  // 实现copy协议方法
  - (id)copyWithZone:(NSZone *)zone
  {
  Person *p = [[Person allocWithZone:zone]  init];
  p.name = self.name;
  p.age = self.age;
  return p;
  }

调用!
Person *p3 = [[Person alloc] init];
p3.name = @"tom";
p3.age = @"20";
// 使用copy创建
Person *p4 = [p3 copy];
NSLog(@"--- %d ---", LINE);
NSLog(@"%@, %@", p4.name, p3.age);
NSLog(@"%lu", [p3 retainCount]);
// p4 的引用计数是多少?
NSLog(@"%lu", [p4 retainCount]); // 用copy 计数 会+1;

  • dealloc
    • dealloc是继承自父类的方法,当对象引用计数为0的时候,由对象自动调用。用于释放内存区域;
    • 必须重写delloc方法, 在.m文件中
  • 加入数组的时候, 对象retain一次, 引用计数+1;
    Person *p5 = [[Person alloc] init];
    [arr addObject:p5];
  • 对象移除数组的时候, 对象release一次, 引用计数 -1;
    [arr removeObject:p5];
    添加和删除, 系统内部都帮你实现了!
内存管理原则;
- 引用计数的增加和减少相等,当引用计数降为0之后,不应该再使 用这块内存空间;
- 凡是使用了alloc、retain或者copy让内存的引⽤用计数增加了,就需要使用release或者autorelease让内存的引用计数减少。在一段代码内,增加和减少的次数要相等。 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容

  • 导读 一、为什么要进行内存管理 二、内存管理机制 三、内存管理原则 四、MRC手动内存管理 五、ARC自动内存管理...
    千山小畻阅读 2,050评论 0 7
  • 今天看到一篇不错的文章关于OC内存管理的,转载一下与你共享概述我们知道在程序运行过程中要创建大量的对象,和其他高级...
    niceSYT阅读 452评论 0 2
  • OC采用了引用计数(retain count)对对象内存进行管理,例如,某个对象alloc了,那么这个对象的...
    轻云_阅读 610评论 0 4
  • 1.内存的创建和释放让我们以Object-c世界中最最简单的申请内存方式展开,谈谈关于一个对象的生命周期。首先创建...
    年轻皆浮云阅读 272评论 0 0
  • 我的眼睛会越变越小吗? 小得看不见月亮, 看不清星星, 不能直视白天的阳光。 小得看丢了积木, 戴上了眼镜 反射出...
    此君邪阅读 155评论 0 1