iOS 内存管理

2020-05-03  本文已影响0人  灵源初归

内存管理的原理

iOS 内存管理,是基于引用计数来管理内存;当对象引用计数为0时,对象将被销毁,回收内存空间;内存管理的法则是谁持有的,谁负责释放;

1. 自己生成的对象,自己持有

2.非自己生成的对象也能持有

3.不需要自己持有自己持有对象时,需要释放

4.无法释放非自己持有的对象

内存管理的两种模式

iOS内存管理分为两种模式:MRC和ARC

最开始内存管理,程序员需要自己管理对象的引用计数,就是我们熟知的MRC

后来苹果进行的改革,采用ARC模式,在编译阶段,自动对代码优化,加入release 的释放内存的操作,解放了程序员,当然这是简单的理解;其实还涉及到运行时的一些内容,我们可以简单从ARC要从以下两方面支持可以了解到:

1. clang(LLVM编译器)3.0以上

2.objc4 Objective-C运行时库493.9以上

影响引用计数的几种方式

1. 导致引用计数加1

alloc、new、copy、mutableCopy 这几个关键操作会产生一个新的对象,引用计数为1

retain:MRC下的操作,会使对象的引用计数加1

在ARC ,用一个强引用指针指向一个NSObject对象,会导致NSObject对象的引用计数加1

id __strong obj = [[NSObject alloc] init]; // 此时 obj的引用计数为1
id __strong obj1 = obj; // 此时obj的应用计数为2

2.引用计数减1

release: 当然这是MRC下才能使用了

3.不会对引用计数产生变化

weak 、assign修饰的变量,两者区别weak修饰对象释放后指针指向nil,assign则不然,另外assign可以修饰一些字面量;

ARC 的一些规则

不能使用retain、release、retainCount、autorelease方法

不能使用NSAllocateObject、NSDeallocateObject函数

不要显式调用dealloc

使用@autoreleasepool块代替NSAutoreleasePool

需遵守内存管理命名规则

1)alloc、new、copy、mutableCopy等以这些名字开头的方法都应当返回调用方能够持有的对象2)init开头的方法必须是实例方法并且要返回对象,返回值要是id或者该方法对应类的对象类似或者其超类或者其子类。另外,init开头的方法也仅仅用作对对象进行初始化操作

不能使用区域(NSZone)

对象型变量不能作为C语言结构体的成员

显式转换"id" 和 "void*"

循环引用

聊到内存,无法避免聊到循环引用

循环引用的实质:多个对象相互之间有强引用,不能释放让系统回收。

如何解决循环引用:

1. 避免产生循环引用,通常是将 strong 引用改为 weak 引用。

2. 在合适时机去手动断开循环引用。

几种常见的循环引用

1. 代理(delegate)循环引用属于相互循环引用

delegate 是iOS中开发中比较常遇到的循环引用,一般在声明delegate的时候都要使用弱引用 weak,或者assign,当然怎么选择使用assign还是weak,MRC的话只能用assign,在ARC的情况下最好使用weak,因为weak修饰的变量在释放后自动指向nil,防止野指针存在

2. NSTimer循环引用属于相互循环使用

在控制器内,创建NSTimer作为其属性,由于定时器创建后也会强引用该控制器对象,那么该对象和定时器就相互循环引用了。

如何解决呢?

这里我们可以使用手动断开循环引用:

如果是不重复定时器,在回调方法里将定时器invalidate并置为nil即可。

如果是重复定时器,在合适的位置将其invalidate并置为nil即可

3. block循环引用

并不是所有block都会造成循环引用。

weak 原理简单分析

autorelease 再认识

上一篇下一篇

猜你喜欢

热点阅读