ARC

ARC

1、ARCAutomatic Reference Counting(自动引用计数器)的简称。

ARC是ios5.0引入的新特性,完全消除手动管理内存的繁琐,编译器会自动在适合的代码里面插入适当的retain,release,autorelease的语句。我们不要再担心内存管理,因为编译器帮我们做了这一切。
ARC是编译器的特性,并非运行时的特性

2、基本原理

ARC的规则就是只要对象没有强指针引用,就会被释放掉,换而言之 只要还有一个强引用指针变量指向对象,那么这个对象就会存在内存中。弱指针指向的对象,会被自动变成空指针(nil指针),从而不会引发野指针错误。

AutoreleasePool

参考:
https://www.jianshu.com/p/b75a99892261

自动释放池存储于内存中的栈并遵循"先进后出"原则,因为它是将数据存储在栈的容器中。因此就出现先进后出原则

1、介绍

autoReleasePool和ARC都是iOS5.0出来的,AutoreleasePool(自动释放池)是OC中的内存自动回收机制,它可以延迟自动释放池中变量release的时机。在正常情况下,创建的变量会在超出其作用域的时候release,但是如果将变量加入AutoreleasePool,那么release将延迟执行。

2、ARC下使用场景

苹果官方给的建议之一是 循环中包含了大量临时创建的对象。
除此之外,当函数写的很长,在中间出现很多变量,占据大量内存也可以使用

ARC下用 @autoreleasepool {}主要还是为了避免内存峰值。
正常情况下,你创建的变量会在超出其作用域的时候被释放掉。
而如果你的函数写的很长,在你函数运行过程中出现很多中间变量,占据了大量的内存,怎么办?
用@autoreleasepool。在@autoreleasepool中创建的变量,会在@autoreleasepool结束的时候执行一次release,进行释放。其实@autoreleasepool就相当于一层作用域。

3、autorelease的优化

1)优化内存,在for循环创建的时候,使用@autoreleasepool 包起来,让每次循环结束时,可以及时释放临时对象的内存

4、解释

@autoReleasePool什么时间释放? 每次Runloop结束时会有专门的时机用来释放

5、用法

@autoreleasepool {
// code do something, creates some autoreleases objects
}

6、autorelease使用注意:

1.占用内存大的对象不要随便使用autorelease,担心对象释放的时间太迟

2.占用内存小的对象使用autorelease,没有太大影响
autoreleasepool:在iOS程序运行时,会创建无数个池子,这些池子以栈结构存在(先进后出);当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池。

7.堆和栈的区别:

.text段 : 存放代码

.data区 : 存放全局变量

堆区 : 存放对象,需要程序员手动释放

栈区 : 存放局部变量 ,程序自动管理内存

8.引用计数器

  • 用来表示对象被引用的次数,当为0时,会被回收,新对象被创建时,默认为1
  • retain +1, release -1, retainCount查看
  • 当对象的的引用计数器为0时,它将被销毁,系统会向对象发送一条dealloc消息,dealloc就像对象的遗言,要重写dealloc方法,并且在调用[super dealloc]方法时,一定要放在最后
    当使用new alloc copy等关键字时,引用计数器会+1
    使用release或者autorelease时会-1

9.常见错误

1.僵尸对象:引用计数器为0的对象为僵尸对象

2.野指针:指向僵尸对象的指针 继续释放会崩溃 EXC_BAD_ACCESS(code=1,address=)

3.空指针:没有指向任何东西的指针

4.防止野指针出现常用方法:p=nil

10.循环引用问题的出现:相互retain

解决思路:
1、一段使用retain,另一端使用assign

2、使用assign段中,在dealloc方法中不需要释放对方

11.ARC

1.不允许调用release、retain、retainCount

2.允许重写dealloc,但是不允许调用[super dealloc]

12.ARCMRC混用

1.自己的旧项目没有使用ARC,但是引入的第三方库却是使用了ARC的。
(给采用了ARC的源文件,添加-fobjc-arc选项)

2.自己的新项目使用了ARC,但是引入的第三方库或者以前写的代码却没有使用ARC。
(添加-fno-objc-arc) build Phases找到相应的类,添加-fno-objc-arc

13.使用block时什么情况会发生引用循环,如何解决?

一个对象中强引用了block,在block中又使用了该对象,就会发生循环引用。
解决方法是将该对象使用__weak或者__block修饰符修饰之后再在block中使用
__weak __typeof(&*self)weakSelf = self 调用外部方法
id __block weakSelf = self; 在block内部修改外部变量的值

 #define WS(weakSelf)  __weak __typeof(&*self)weakSelf = self;
 
 WS(weakSelf)
 [self.tableView addHeaderWithCallback:^{
    [weakself requestMemberList];
 }];

14.Objective-C如何对内存管理的,说说你的看法和解决方法?

  1. 每个对象都有一个引用计数器,每个新对象的计数器是1,当对象的计数器减为0时,就会被销毁
    2.通过retain可以让对象的计数器+1、release可以让对象的计数器-1
    3.还可以通过autorelease pool管理内存

4.如果用ARC,编译器会自动生成管理内存的代码
注意:不管是MRC还是ARC都是在编译时完成的

15.内存管理的几条原则时什么?按照默认法则.哪些方法生成的对象需要手动释放?在和property结合的时候怎样有效的避免内存泄露?

1.只要调用了alloc、copy、new方法产生了一个新对象,都必须在最后调用一次release或者autorelease
2.只要调用了retain,都必须在最后调用一次release或者autorelease
3.@property如果用了copy或者retian,就需要对不再使用的属性做一次release操作
4.如果用了ARC,另外讨论

16.看下面的程序,三次NSLog会输出什么?为什么?

    NSMutableArray* ary = [[NSMutableArray array] retain];
    NSString *str = [NSString stringWithFormat:@"test"];
    [str retain];
    [ary addObject:str];
    NSLog(@"%ld", (unsigned long)[str retainCount]);
    [str retain];
    [str release];
    [str release];
    NSLog(@"%ld", (unsigned long)[str retainCount]);
    [ary removeAllObjects];
    NSLog(@"%ld", (unsigned long)[str retainCount]);
结果:-1、-1、-1 。-1代表没有引用计数或者引用计数非常大,因为str是字符串,字符串在常量区,没有引用计数。引用计数为-1,这可以理解为NSString实际上是一个字符串常量,是没有引用计数的(或者它的引用计数是一个很大的值(使用%lu可以打印查看),对它做引用计数操作没实质上的影响)

17.写一个setter方法用于完成@property (nonatomic,retain)NSString *name,写一个setter方法用于完成@property(nonatomic,copy)NSString *name.
@property (nonatomic, retain) NSString *name;

- (void)setName:(NSString *)name
{
  if (_name != name) {
    [_name release];
    _name = [name retain];
  }
}
2>  @property(nonatomic, copy) NSString *name;
- (void)setName:(NSString *)name
{
  if (_name != name) {
    [_name release];
    _name = [name copy];
  }
}

18.Objective-C使用什么机制管理对象内存?

MRC 手动引用计数
ARC 自动引用计数,现在通常 ARC
通过 retainCount 的机制来决定对象是否需要释放。 每次 runloop 的时候,都会检查对象的 retainCount,如果 retainCount 为 0,说明该对象没有地方需要继续使用了,可以释放掉了

19.ARC下还会存在内存泄露吗?

循环引用会导致内存泄露.
Objective-C 对象与 CoreFoundation 对象进行桥接的时候如果管理不当也会造成内存泄露.
CoreFoundation 中的对象不受 ARC 管理,需要开发者手动释放

20>Objective-C 如何对内存管理的,说说你的看法和解决方法?

答:Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。
1). 自动内存计数ARC:由Xcode自动在App编译阶段,在代码中添加内存管理代码。
2). 手动内存计数MRC:遵循内存谁申请、谁释放;谁添加,谁释放的原则。
3). 内存释放池Release Pool:把需要释放的内存统一放在一个池子中,当池子被抽干后(drain),池子中所有的内存空间也被自动释放掉。内存池的释放操作分为自动和手动。自动释放受runloop机制影响。

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