iOS 的内存管理

一.内存管理的原因

(1)内存溢出 内存不够用

(2)野指针异常 指针操作了不属于自己的存储空间,指针操作已经销毁的对象

二.内存管理的方式

(1)MRC  手动管理内存

(2)ARC  自动管理内存

三.MRC手动管理内存

1.引用计数器

(1)引用计数器表示有多少人正在使用这个对象。

(2)当没有任何人使用这个对象时, 系统才会回收这个对象, 也就是说当对象的引用计数器为0时,对象占用的内存就会被系统回收。

(3)如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收(除非整个程序已经退出 )

(4)任何一个对象, 刚生下来的时候, 引用计数器都为1

(5)当使用alloc、new或者copy(MutableCopy)创建一个对象时,对象的引用计数器默认就是1

2.引用计数器的操作

(1)给对象发送一条retain消息,可以使引用计数器值+1(retain方法返回对象本身)

(2)给对象发送一条release消息, 可以使引用计数器值-1

(3)给对象发送retainCount消息, 可以获得当前的引用计数器值(retainCount有时候会不准确,建议采用delloc方法来验证是否完全内存释放)

注意: release并不代表销毁\回收对象, 仅仅是计数器-1

3.dealloc方法

(1)当一个对象的引用计数器值为0时,这个对象即将被销毁,其占用的内存被系统回收。

(2)对象即将被销毁时系统会自动给对象发送一条dealloc消息 (因此, 从dealloc方法有没有被调用,就可以判断出对象是否被销毁)

dealloc方法的重写:

一般会重写dealloc方法,在这里释放相关资源,dealloc就是对象的遗言

一旦重写了dealloc方法, 就必须调用[super dealloc],并且放在最后面调用

-(void)delloc{

[super delloc];

}

4.使用注意

不能直接调用dealloc方法

一旦对象被回收了, 它占用的内存就不再可用,坚持使用会导致程序崩溃(野指针错误).

5.内存管理规则

(1)谁创建谁release :

如果你通过alloc、new或[mutable]copy来创建一个对象,那么你必须调用release或autorelease。

谁retain谁release:

(2)只要你调用了retain,就必须调用一次release

总结:

有加就有减

曾经让对象的计数器+1,就必须在最后让对象计数器-1,最后重写delloc方法来检查内存是否完全释放。

6.多对象内存管理

(1)多对象内存管理规则:

只要还有人在用某个对象,那么这个对象就不会被回收

只要你想用这个对象,就让对象的计数器+1

当你不再使用这个对象时,就让对象的计数器-1

(2)setter方法内存管理规则:

retain需要使用的对象

release之前的对象

只有传入的对象和之前的不同才需要release和retain

- (void)setRoom:(Room *)room

{

// 避免过度释放(判断私有成员和局部成员是否相等)

if (room != _room)

{

// 对当前正在使用的车(旧车)做一次release

[_room release];

// _room = nil;

// 对新车做一次retain操作

_room = [room retain];

}

}

(3)dealloc方法的内存管理规则

- (void)dealloc

{

// 当人不在了,代表不用房间了

// 对房间做一次release操作

[_room release];

// 这样写逼格高一点  self.room = nil;

[super dealloc];

}

7.@property参数

这里写图片描述

(1)控制set方法的内存管理

retain : release旧值,retain新值(用于OC对象)

assign : 直接赋值,不做任何内存管理(默认,用于非OC对象类型)

copy : release旧值,copy新值(一般用于NSString *)

(2)控制需不需要生成set方法

readwrite :同时生成set方法和get方法(默认)

readonly :只会生成get方法

(3)多线程管理

atomic :性能低(默认)

nonatomic :性能高(iOS开发中都用这个属性)

(4)控制set方法和get方法的名称

setter : 设置set方法的名称,一定有个冒号:

getter : 设置get方法的名称

若有bool类型时最好修改getter方法为:(getter = isXXX)

注意: 不同类型的参数可以组合在一起使用

(5)循环引用

当使用@property属性声明两个对象时,如果同时使用retain,会到时相互引用,内存不会释放,解决办法是,一个用retain,一个用assign。

8.autoreleasepool 自动释放池

(1)在iOS程序运行过程中,会创建无数个池子。这些池子都是以栈结构存在(先进后出),当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池。

(2)autorelease是一种支持引用计数的内存管理方式,只要给对象发送一条autorelease消息,会将对象放到一个自动释放池中,当自动释放池被销毁时,会对池子里面的所有对象做一次release操作

注意:

这里只是发送release消息,如果当时的引用计数(reference-counted)依然不为0,则该对象依然不会被释放。

(3)autorelease使用注意事项

并不是放到自动释放池代码中,都会自动加入到自动释放池

在自动释放池的外部发送autorelease 不会被加入到自动释放池中

autorelease是一个方法,只有在自动释 放池中调用才有效。

如果写了autorelease就不要写release

只要在自动释放池中调用autorelease, 就会将对象放入自动释放池

自动释放池中不适宜放占用内存比较大的对象

不要连续调用autorelease,同时也不要把大量循环操作放到同一个 @autoreleasepool 之间

@autoreleasepool {

// 创建对象时用autorelease

Person *p  =[ [Person alloc]init]autorelease];

}

// 类方法

+(instancetype)person{

return [[self alloc]init]autorelease]

}

// 类工厂方法

+(instancetype)personWithAge:(int)age

{

return [[[self alloc] initWithAge:age] autorelease];

}

-(void)dealloc

{

NSLog(@"%s", __func__);

[super dealloc];

}

四、ARC 自动引用计数管理内存

1.ARC机制判断注意点及优点

ARC机制判断,ARC机制下有几个明显的标志:

不允许调用对象的release方法

再重写父类的dealloc方法时,不能再调用 [super dealloc];

ARC的注意点:

- ARC是编译器特性,而不是运行时特性

- ARC不是其它语言中的垃圾回收,有着本质区别ARC的

优点:

- 完全消除了手动管理内存的烦琐

- 基本上能够避免内存泄露有时还能更加快速,因为编译器还可以执行某些优化

2.强指针,弱指针

强指针

默认所有指针变量都是强指针

被__strong修饰的指针

Person *p1 = [[Person alloc] init];

__strong  Person *p2 = [[Person alloc] init];

弱指针

被__weak修饰的指针

__weak  Person *p = [[Person alloc] init];

3.ARC下单对象内存管理

(1)局部变量释放对象随之被释放

(2)清空指针对象随之被释放

(3)默认清空所有指针都是强指针

弱指针需要明确说明 :

注意: 千万不要使用弱指针保存新创建的对象

4.ARC下循环引用问题

与MRC一样,当两个对象相互引用时,会出现内存泄露的问题,解决办法是:一个用strong一个用weak。

5.ARC下@property参数

strong: 用于OC对象, 相当于MRC中的retain

weak: 用于OC对象, 相当于MRC中的assign

assign: 用于基本数据类型, 跟MRC中的assign一样(默认值)

五.如何将MRC转换为ARC

如何进行ARC和MRC的混合使用:

转变为非ARC -fno-objc-arc

转变为ARC的, -f-objc-arc (不常用)

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

推荐阅读更多精彩内容