iOS 内存理解

对于iOS开发者来说,第一个要过的关大概就是iOS的内存管理吧。

那么我第一篇就从iOS的内存管理讲起:

iOS内存管理编程指南指出Objective-C提供了三种内存管理方式:

1.Manual Retain-Relaease

开发者使用由NSObject和Runtime共同提供的引用计数模型,自己用代码来管理内存。

2.Automatic Reference Counting

ARC 自动引用计数 和MRR一样同样采用引用计数,但是在编译时插入内存管理的方法。这里ARC自动地帮助我们处理了引用计数相关的内存操作。

3.Garbage Collection

垃圾回收。系统对于没有引用的对象,自动化回收处理。Mac OS下使用,iOS不可以。

无论是内存管理指南 还是 其他一些讲到有关iOS内存管理的书籍,都会提到内存管理的方式:

1.自己生成的对象自己拥有(以alloc/new/copy/mutableCopy来头的方法)

2.可以通过retain持有一个对象

3.不再需要一个对象时,要放弃对象的持有

4.使用中的对象不要进行release(引起crash)

ps:对于一些以alloc/new/copy/mutableCopy开头的方法却并不属于上面所说的情况,如:newer,copying,allocate等。对于一些能够得到对象,自己却不持有的例子如[NSMutableArray array],其实是使用autorelease 实现的。

autorelease的使用:

首先生成autopool 然后对象a调用autorelease把a对象放入autoPool中,autoPool调用drain相当于对pool内所有的对象进行release

ps:autopool对象不可以使用autorelease方法。

ARC:

__strong 修饰符

所有的对象前缀都默认加上了__strong;


在ARC环境中这两个的意思是一样的

__strong 修饰的变量在超出它的作用域的时候会自动释放,相当于调用了一次releease

就算是

使用非alloc/new/copy/mutableCopy开头的类方法

因为是__strong强引用 也会变成自己持有。

ps:

原封不动的返回用alloc生成的对象,就能让调用方也持有该对象

__weak 修饰符

因为__strong会出现循环引用问题 所以引入了__weak修饰符


声明__weak修饰的变量对象

因为__weak修饰的变量持有对象的弱引用,生成的对象会被立即释放。

_unsafe_unretained

使用_unsafe_unretained修饰的对象不属于编译器的内存管理对象。

它和__weak修饰符一样都不持有对象,所以生成的对象会被立即释放。但是它和weak不同的是,在对象被释放时weak修饰的指针变量会被设置成nil 而 _unsafe_unretained不会。

__autoreleasing 修饰符

ARC 中NSAutoReleasePool的代替

在写的时候我们很少会加上__autoreleasing修饰符

不使用修饰


生成并非自己持有的对象,由编译器判断它的方法名后自动注册到autoreleasepool

因为没有指定修饰符,所以默认是strong,因为return让变量超出了作用域,所以该强引用的对象会被释放,但是作为函数返回值编译器会自动把它加入到autoreleasepool。

ps:访问__weak修饰符的变量时,必定会访问注册到autoreleasepool的对象。__weak持有对象的弱引用,在访问过程中,对象可能被废弃。所以会把对象注册到autoreleasepool中,保证在autoreleasepool结束之前都可以确保对象存在。

ps: id *类型 默认修饰符是 __autoreleasing

ps:需要注意的是在ARC环境中要显式转换id和void *

这时可以使用__bridge 

这种转换的安全性和使用_unsafe_unretained类似

__bridge有两种__bridge_retained和__bridge_transfer

__bridge_retained 这种转换让a和p和b同时持有该对象

__bridge_transfer这种变换先让p持有对象 释放a 然后让b持有对象释放p

通常用来于CF之间的转换。

你可能感兴趣的:(iOS 内存理解)