对于开发者来说,内存管理几乎是一个永恒的话题。

内存管理对于编写出高效率的iOS APP是非常重要的,这是因为iOS是多任务系统,在同一时刻可能有多个应用程序共享内存,有时为了使某个任务更好地执行,iOS系统可能会对其它任务分配的内存进行移动,甚至删除。

现在被广泛使用的内存管理机制主要有GCRC两种。 GC:垃圾回收机制,定期查找不再使用的对象,释放对象占用的内存。 RC:引用计数机制,采用引用计数来管理对象的内存,当需要持有一个对象时,使它的引用计数+1,当不需要再持有一个对象的时候,使它的引用计数-1;当一个对象的引用计数为0时,该对象就会被销毁。

Objective-c支持三种内存管理机制:GC,MRC,ARC。以前MacOS开发中是支持GC的,后面引入ARC后就弃用了GC机制。iOS开发中使用的是RC机制,从MRC到现在的ARC

###引用计数 可以看我之前的一篇关于引用计数

###MRC时代 基本内存管理规则:MRC下是要严格遵守引用计数内存管理规则。 内存管理模型是基于对象的所有权。任何对象都可以拥有一个或者多个所有者,但是一个对象最少要拥有一个所有者,它才会继续存在。如果对象没有所有者的,它将会被销毁。

####四条内存管理策略: 1.自己生成的对象,自己持有 alloc/new/copy/mutableCopy等方法创建的对象,我们自己直接持有,它的RC初始值为1,我们可以直接使用,不需要使用的时候调用release释放。

2.非自己生成的对象,自己也能持有。 不通过上面方法创建的对象,它的RC初始值也为1,但是我们不能直接使用,要先调用retain,否则可能会crash。原因是因为这些方法内部是给对象调用了autorelease方法,所以这些对象是被添加到了自动释放池中了。

两种情况,程序没有手动指定@autoreleasepool,当runloop迭代结束时,会自动给释放池中的对象调用release方法。如果我们使用前不进行retain,刚好runloop迭代结束,对象的RC从1变成0,然后就被销毁了.我们去访问一个已经被销毁的对象,程序就会crash。 程序手动指定了@autoreleasepool,当时出了其作用域,对象会调用release方法,然后销毁,这个时候使用对象也会crash

3.不再需要自己持有的对象时,释放。 不再需要持有或者使用对象的时候,就调用release或者autorelease方法进行释放。rc变成0时,就会调用dealloc方法销毁。 release立马rc-1autorelease加入自动释放池,在合适的时候rc-1,实际上就是延迟释放。

4.非自己持有的对象,无需释放。 自己不是持有者,调用release的话,会crash

####实用的内存管理原则 使用访问器方法可以省略大量的retainrelease 推荐使用访问器方法设置属性,一个是可以避免忘记写retainrelease,第二个是触发kvo 不要在初始化和dealloc中使用访问器方法,原因是在初始化中使用访问器方法,self=[super init],首先会调用父类的访问器方法,然后如果子类重写了访问器方法,会去调用子类的访问器方法,而这个时候,子类实际上是没有初始化的,所以会出错。dealloc实际上是个反向的。就是子类先释放,再去调用父类。就是调用父类的dealloc时,会调用父类的访问器方法,如果子类重写了该访问器方法,就会去调用子类的访问器方法,但是子类已经释放掉了,也会出错。还有一个原因就是会触发KVO,在准备释放前,触发了kvo,即将释放的对象被持有了。就是出现莫名其妙的错误。 推荐使用@autoreleasepool,虽然mrc下,可以使用NSautoreleasepool,但是速度慢很多。 1.写的程序是非UI框架,比如命令行工具 2.循环创建大量的临时变量。 3.多线程中。比如创建辅助线程。

###ARC时代 ARC时代,内存管理基本都交给编译器来处理了,对于开发者来说是十分友好了。 ARC的编译器有两部分,前端编译器和优化器。前端编译器会对每一个对象插入相应的release语句。类拥有的对象会在dealloc中释放。方法内创建的对象,前端编译器会在方法末尾自动插入release语句销毁它。优化器负责移除多余的retainrelease操作语句。

但是还是有些地方需要注意的。

新增的几个关键字: __strong 强引用,用来保证对象不会被释放。 __weak 弱引用 释放时会置为nil __unsafe_unretained 弱引用 可能不安全,因为释放时不置为nil。悬垂对象。 __autoreleasing 对象被注册到autorelease pool中方法在返回时自动释放。

####block使用中出现循环引用

_ _ _ _ } p p p _ p ; e e e w e r r r e r s s s a s d } o o o k o _ i ) n n n n t s ; 1 2 2 1 y p . _ . p a N = = n t b e t S a y l o c L [ [ m p o f h o [ [ e e c ( _ g P P o k & a ( e e = f * f @ r r ( = w t " s s @ s e e % o o " e ^ a r @ n n l { k ( " f S d , a a " ) e i s l l ; l s t l l w f p r o o e ) a o c c a t n ] ] k s c g S t h S i i e r _ e n n l o t l i i f n i f t t g m . ] ] = S e p ; ; e ( e s l D r e f I s l S o f = P n ; A 2 w T . e C n a H a k _ m S T e e I ) l M ; f E ; _ N O W , ( i n t 6 4 _ t ) ( 5 N S E C _ P E R _ S E C ) ) , d i s p a t c h _ g e t _ m a i n _ q u e u e ( ) , ^ {

使用weakSelf结合strongSelf的情况下,能够避免循环引用,也不会造成提前释放导致block内部代码无效。 在MRC下,应该使用__block。

####NSTimer循环引用 使用category处理。

@ } } @ i e m ( n p N d l S r o i } e T e i o f m i t d i e m u ) d ( n e r b ( b b t r n l ^ l l a _ b o o t [ b l c c i ) s l o k k o b e o c ) ( n l l c k ) _ f k ) { ; N s S ( S c s e v T h c l o i e h e i m d e c d e u d t ) r l u o e l r = ( d e : B T d ( t l i T N i c m i S m o e m T e k r e i r T W r m . i i W e u m t i r s e h t e r T h r ) i T ) I m i t n e m i f I e m o n I e ; t n r e t r e { v r a v l a : l ( : N i S n T t i e m r e v I a n l t e t r a v r a g l e ) t i : n s t e e l r f v a s l e l b e l c o t c o k r : : ( @ v s o e i l d e c t o r ( b o l i _ d b ) l ) o b c l k o S c e k l e r c e t p o e r a : t ) s : u ( s B e O r O I L n ) f r o e : p [ e b a l t o s c k { c o p y ] r e p e a t s : r e p e a t s ] ;

使用中间件,利用runtime,self依赖timer,time依赖中间件,中间件弱引用self

@ @ @ @ } } } } } i p e i n r n m ( ( ( ( t o d p i i i B e p l n _ r n r d r o [ O r r e e s w e s e ) e i o i O e f r m t e t t t f t d i n L t a t e a a u a u o u ) d v ) u c y n n k r n r r r f o r r e t c O n c n _ w n o * c e n ( a e b e w a r n a s W w t t j s t [ e r _ w u t p [ e e i y e e y [ a d w a l i o _ a a o p c l p W k i e r l o n w k k n e t f e e O n a d n d e O , ) ; ) a b g k I = s a b W i = p k j T O n s T k j n e n r O e a b v N e o O e o a i o o b c r j o U t S b c n k t b x j t g e c L R e j t a O W j y e e c a L e l e ( t b i ; W c t t t ; t e c ) o j t i t F ; i u c t m e h t o o r t i c W h a r n n o r c t e W l S : V r e ) a e l e ( a : s k a o l N l ( p i O k c e S u S o d b O ] c I e E n j b t n : L d w e j i o v & ) s e c e n r o n a T a t c i : c u S o k : t t ( a l e S O ( : W S t l l e b i ( i E i ] e l j d i t L o ; c e e ) d h ) n t c c o ) W a o t t b o e S r o ; j b a e ) r j k l i { : { O e n a { b c v S j t o e e o c l c r a e t t c : { i t o o o b n r j ] ] { ; ;

使用method swizzing,利用Method Swizzling,通过替换原有的接口,将循环引用的对象改为弱引用。

# { M M m } { } { } / d \ e e e e t t t ( f h h h C N i o o o o l S t N t t } w r n d d d i / a T y / S y / i ; e e e _ d s i p T p m a t i m e ) s m e i e e k u C m y x l M e o m o b r i { } I f T r l p I c o e r f e f l . f M o u i n a m h a t ( r ( o f P i n m s = p a d h a N c c ( d c e t s n o ) T * S k T ! r i ( i M c = g d s a t T i w e m w = m e l e S c r i i m e t p * e e t a c I w h g m m e a u f a t r h s l m i e e e e r k r = u k i ; o s a p z d t r r B T n n T m d _ s l z u ) l a ; [ c a e S g s e l l = o r w ) r r w e _ m i e c g e ( g ; i t g e n d _ [ k e a i e z I e n g T w s t k d t z n t t ( i e e _ = ) T , , l s I a s m a l w a i t n t c e k f e r S a n a s i h r a g E S g n t o e W w s k e L e ( c a n d i e c o t , l f e n s u t a h w i e u M c ( l h k e e d m i c n e e i e T T d a ) e d t c t M m d i a u k { t ) o 0 h e p T m r l T h r , o t , i e g e i o = , d h m I e d m d w f ( o m e n t T e F e u o d y r t i o a n b ( I W e = m = r o k c j o m i r e S i T 1 e b p t v a r t e d i ) c j ) h a T W i l m t e ; T l a i m e e _ c \ i : r t e c ) ) g t m ( g h r t i ; e _ e N e T ; o m t g I S t i r p C e n T ; m : ; l t t i e a a C e m I S s l r e n e s a v I t l ( s a n e e [ s l t r c s ( : e v t e [ t r a o l s a v l r f e r a : ] l g l i ; c f e ) n l t i t a c : n e s l s t r s a e e v ] s l r a ) s e v l , ] c a ) t l t @ , o a s r t r e @ : a g l s u r e e e s g t c l e e : t e r t s o c I : e r t n ( l ( o f i f f r o d u ( : ) s n f r a e c u e T l 0 n p a e ) c e r c ) 1 a g t ; ) t e o \ ) s t r ; : : \ , s @ e s f l e c e l _ c e s t c c o t h r o e : r d ( ( u S f l E c e L _ d ) b T a l i S o m e c e l k r e I W c n i t v t o o h r k T e i u : m s ) e e I r u n I s t n e e f r r o I v : n a ( f l n o : u : t l u a l s r a e g b r e l I t e n : f s i o e d l ) r e u e c s p t e e o r a r I t : n s u f : s o y e e r r s I e O n p r f e N o a o : t ] r s ; e : p ( e B a O t O s L : ) ) y ; e s O r N o