iOS小筑

iOS开发基础之内存管理

2015-12-05  本文已影响176人  华子小筑

为什么要进行内存管理

如何进行内存管理

使用引用计数的方式对创建的对象进行内存的管理操作;有强引用指向(retain)那么引用计数+1,强引用被置为nil(release)那么引用计数-1;对象超过作用域该对象的引用计数如果为0,则系统会清理对象占用的内存空间,目前内存管理的方式分为MRC和ARC两种.

引用计数是什么

内存管理的思考方式

autorelease的作用

autorelease的实现 (GNUStep)

autorelease的实现 (Apple)

autorelease的实现

autoreleasepool

手动创建autoreleasepool的情况

当开发中遇到在某个作用域内部产生大量的autorelease对象导致内存激增,需要考虑手动创建autoreleasepool来释放局部变量的情况!

所有权修饰符

__strong

持有强引用的变量会在超过其作用域的时候被释放;对应属性中的retain/strong;默认情况下的所有权修饰符是__strong;

 {
   // 自己生成并持有对象
   id _strong obj = [[NSObject alloc]init];
 }// 超出作用域,强引用失效,释放对象  
__weak
{  
 id obj = [[NSObject alloc]init];
 id __weak weakObj = obj;   
} 
__unsafe_unretained

和weak相似但不会在对象被销毁时自动置为nil(属性中对应assgin)
对于weak来说__unsafe_unretained性能上更加优越

__autoreleasing

类似调用autorelease方法将对象添加到自动释放池中

内存管理开发tips

ARC与Block的内存管理

block为什么会导致循环引用?
当self对象持有block,在block中也持有self;在block中会copy一个self对象作为block的一个属性;当要该属性的释放要等到block从堆中移除,而此时block要等待持有自己的self销毁,由此导致循环引用;
解决方法:弱化self对象,但要在block内不防止弱化的对象过早释放,由此在block中还得再次强化已弱化的self对象

属性的set方法MRC下的内存管理的写法

 -(void)setName:(NSString*)newName{
   [newName retain];
   [_name release];
   _name = newName;  

自动释放池和线程

Cocoa程序中的每一个线程,都维护自己的自动释放池栈。如果你要写一个Foundation程序,或者卸载一个线程,你需要创建自己的autorelease池块。如果你的程序或者线程是常驻内存,并可能产生大量自动释放对象,你应该使用自动释放池(AppKit和UIKit在主线程中有自动释放池);否则自动释放对象累积,导致内存占用增长。如果你不是Cocoa中卸载线程,你不需要使用一个自动释放池块。

控制器移除时dealloc无法被调动

遇到这种情况,就需要排查控制器中出现的内存泄露了;

上一篇 下一篇

猜你喜欢

热点阅读