内存管理

一. 内存管理的认识

1.概念的认识

内存管理:一个程序在运行时给其分配内存,程序运行结束释放内存的过程。
移动设备的内存是有限,每个程序都会分配一定的内存,如果程序的需求超出内存限额,就会产生程序崩溃。因此,要确保内存在需要的时候分配,使用结束时及时释放。
编写良好的程序,会尽可能少占用内存,在使用结束时及时将内存释放。

2.常见的问题

【内存泄露】一个堆空间使用完毕后没有及时释放
【提前释放】一个空间没有使用结束就进行释放,造成数据访问不安全
【重复释放】已经被释放过的空间,再次释放,造成程序崩溃

3.内存管理的类型

【自动内存管理】内存的管理交由系统来完成
【手动内存管理】由程序猿(媛)手动的创建堆空间,也有程序猿(媛)手动释放

二.C语言的内存管理

//C中只有开辟在堆中的空间需要手动内存管理,而其余的交由系统进行自动内存管理

1.C的手动内存管理

char * p = malloc(sizeof(1000));
if (!p) {
perror("malloc");
}
p[0] = 'a';
p[1] = 'b';
free(p);

2.存在的不足之处

※堆空间什么时候使用结束难以判断,容易造成提前释放
※当多个指针指向同一堆空间,释放时务必确保只对其中一个进行释放操作,否则造成重复释放
※多人协作编程时,内存管理不灵活,谁来进行释放操作分工难以明确
※从多线程操作角度考虑,当多个线程都要对同一堆空间操作时,只有等最后一个线程操作结束才能进行内存释放,该情况难以确定
//由于C的内存管理存在诸多问题,在OC的实际开发中难以应付,因此OC摒弃了C的内存管理机制,形成了OC独特的内存管理机制

三.OC的内存管理

OC的内存管理采用的是【内置计数器】对内存进行管理 (在Xcode4.2开始使用该机制)

OC的内存管理分为两类:

【MRC】:手动内存管理 内置计数器由程序猿(媛)通过代码来管理
【ARC】:自动内存管理 内置计数器由系统自动进行管理
//从xcode5.0以后 系统默认的内存管理为自动内存管理
【关闭ARC】:工程 —> Tragets —> BuildSetting
—> 搜索 [gar]
[YES] —> [NO]

对象的所有权

//OC的内存管理是基于对象“所有权”的管理

如果实体拥有某一个对象,则这个实体对该对象具有所有权
所有权的拥有意味实体可以对拥有的对象进行清理
指针指向对象,指针作为对象的拥有者可以对对象进行清理
一个为对象可以有一个或者多个“所有者”(可以有一个或者多个指针指向同一个对象)。至少有一个所有者,该对象存在,所有者个数为0时,系统自动析构它,也就是对该对象内存释放

2.引用计数

概念的理解:OC每一个类都是NSObject的子类,因此每一个对象都要一个内置的计数器,该计数器称为【引用计数】(Reference Count),也成为【保留计数】(Retain Count),用于记录对象的拥有者个数的。
使用的原理:
(1)存在第一个拥有者,开辟堆空间存储对象,计数器+1
(2)之后每多一个拥有者(多一个指针指向对象),计数器+1,每少一个拥有者(少一个指针指向对象),计数器-1
(3)当没有拥有者(没有指针再指向对象)认为堆空间使用结束,系统对空间进行释放,通过调用对象的析构方法对对象进行析构。
OC的内存管理就是要维护计数器正确的+1,-1,确保对象能够被正确的释放。

  • (id)retain;+1
  • (void)release; -1
    关于野指针 :已经被释放掉的对象 依然使用原来的指针去调用 这个情况叫野指针问题
    空指针:当对象释放掉的时候 指向对象的所以指针 系统会赋值为空 (p = nil;),指向为空的指针叫做空指针 对空指针发送任何消息 都不起作用
    (主要是为了解决野指针问题)
    例如:创建讨论组

四.MRC内存管理的法则

1.凡是用alloc,retain,new(或使用new开头的方法),copy(或使用copy开头的方法),mutableCopy(或使用mutableCopy开头的方法)【创建】的对象,都必须使用release或autorelease方法【释放】

2.谁创建谁释放(哪个类创建,哪个类释放;谁写alloc,谁写release)。

alloc — release/autorelease
new /new… — release/autorelease
copy/copy… — release/autorelease
mutableCopy
/mutableCopy… — release/autorelease
// [Class new] == [[Class alloc]init]
//copy 和 mutableCopy:只用来复制字符串
【注意事项】
(1)对象的成员变量在构造方法中创建,应在析构方法(dealloc)中释放。
(2)注意指针的转移 释放旧对象 保留新对象。
(3)从数据结构如数组中取出对象地址,如果需要长时间使用,应当retain。
【注】iOS程序中,决不能用类方法长时间使用的对象,如成员变量。

3.自动释放池

@autoreleasepool{
@autoreleasepool{
}
}
NSAutoreleasePool
//自动释放池原本也是对象,为了配合ARC改成了关键字。

  • (id)autorelease;
    //自动释放 / 延迟释放
    【注】自动释放池类似一个数组,进行延迟释放,不会马上计数器减1,而是将当前对象,放入最近的自动释放池。当池释放时,将每个池中的元素释放一次。
    【注】在iOS程序中,每个触发周期,都会创建并销毁一个自动释放池。
    【自动释放原则】
    (1)方法的局部变量可以使用自动释放。
    (2)非用自动释放不可的情况
    【结论】只有一个函数中使用的对象,可以使用类方法创建。类方法创建的对象,使autorelease。

五.【自动内存管理ARC】

//自动引用计数
【提】简单点说就是让编译器完成堆空间的引用计数加减,自动释放。程序员不再写 retain release等方法
【另】OC的自动内存管理,不同于JAVA垃圾回收。而是在预处理时,直接在应该保留的地方,添加retain,在应该释放的地方,添加release。是直接添加代码。
【另】从效率上,ARC优于手动内存管理。

1.ARC的局限

使用ARC,可能因为代码的不规范,导致内存提前释放。
//尤其使用AVAudioplayer类的时候,很可能造成提前释放。
导入一些第三方库,或者导入旧代码,这些代码不支持ARC。

2.解决ARC的局限

(1)将不使用ARC的代码转成ARC代码
Edit —> Refactor —> Convert to ARC
(2)ARC,MRC混编
//同一个工程中,部分文件使用ARC,部分文件使用MRC。
Build phase -----> Complie Source
-fno-objc-arc //单独使用MRC
-fobjc-arc //单独使用ARC

3.使用ARC的技巧

(1)四个关键字 修饰引用
__strong(强引用) 缺省属性,其修饰的对象指针,指向哪个对象,会对该对象retain,离开哪个对象,会对该对象release。
__weak(弱引用)其修饰的对象指针,指向任何对象都不会retain。这样的指针指向的对象随时可能消失。如果对象消失了,这个指针会自动变成nil。
//在iOS编程中,代理对象使用弱引用。避免出现相互调用的问题。
__unsafe_unretained 其修饰的对象指针,指向任何对象都不retain。当指向的对象消失,该指针不会变成nil,仍然指向已经释放的对象
__autoreleasing 只用来修饰需要被传入地址的指针。如:
__autoreleasing NSError * error; &error;
(2) 属性的()参数,原则上,不能写retain copy了,只能写Strong,如果不想retain,写Weak
【注】但实际上ARC对这方面很宽松,写了retain也没关系。
(3) id 指向对象,不能用void * p指向对象。
int a;
void * p = &a;
id p = [[NSObject alloc] init];
(4) C的结构体中,不能声明对象指针。否则这个指针不会进行内存管理
struct sct{
id obj;
};
(5)不能(显式)手动调用父类的dealloc
-(void)dealloc
{
self.name = nil;
//自动调用父类的dealloc
}

六.拓展知识 — 类簇 NSString

NSString *str=[NSString stringWithFormat:@"XXXXXXXXX"];
NSString *str2=@"123";
NSLog(@"%@",str.className);
NSLog(@"%@",str2.className);

由于NSString实质上是由多个类组成的类簇,因此在实际的内存管理上,系统对其进行优化,引用计数不按照常规的规则进行管理
不能通过打印retainCount来单纯判断字符串的对象是否已经被释放
但是依旧可以对类簇依旧按照内存管理的法则进行操作,不影响正常使用。使用时就按照普通的类的对象来管理即可

MRC和ARC的混编

1、如果以前代码少 你知道哪里需要改 Edit - >Convert - >代码转换
2、假设你使用的是别人的三方库 1000个文件 18万
MRC文件 混合到 ARC工程中 Build Phrase->Compile Source -> 选择MRC文件
-fno-objc-arc
ARC文件 换到 MRC工程中 Build Phrase->Compile Source -> 选择ARC文件
-fobjc-arc

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 内存管理 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与a...
    丶逐渐阅读 1,958评论 1 16
  • 29.理解引用计数 Objective-C语言使用引用计数来管理内存,也就是说,每个对象都有个可以递增或递减的计数...
    Code_Ninja阅读 1,477评论 1 3
  • iOS内存管理 概述 什么是内存管理 应用程序内存管理是在程序运行时分配内存(比如创建一个对象,会增加内存占用)与...
    蚊香酱阅读 5,707评论 8 119
  • 内存管理是程序在运行时分配内存、使用内存,并在程序完成时释放内存的过程。在Objective-C中,也被看作是在众...
    蹲瓜阅读 3,037评论 1 8
  • 拿笔随意写写字 好巧 是你的名字
    陌上花开SL阅读 142评论 0 0