频道栏目
首页 > 资讯 > IOS > 正文

【iOS开发】内存管理之基础介绍

17-06-16        来源:[db:作者]  
收藏   我要投稿

前言

【iOS开发】内存管理之基础介绍,内存管理是程序设计中很重要的一部分,程序在运行的过程中消耗内存,运行结束后释放占用的内存。如果程序运行时一直分配内存而不及时释放无用的内存,会造成这样的后果:程序占用的内存越来越大,直至内存消耗殚尽,程序因无内存可用导致崩溃,这样的情况我们称之为内存泄漏。

一、 引用计数

在OC中,对象什么时候会被释放(或者对象占用的内存什么时候会被回收利用)?

答案:当对象没有被任何变量引用的时候,就会被释放。

那怎么知道对象已经没有被引用了呢?

OC采用引用计数(reference counting)的技术来进行管理:
1)每个对象都有一个关联的整数,称为引用计数器
2)当代码需要使用该对象时,则将对象的引用计数加1
3)当代码结束使用该对象时,则将对象的引用计数减1
4)当引用计数的值变为0时,表示对象没有被任何代码使用,此时对象将被释放。

与之对应的消息发送方法如下:

1)当对象被创建(通过alloc、new或copy等方法)时,其引用计数初始值为1
2)給对象发送retain消息,其引用计数加1
3)給对象发送release消息,其引用计数减1
4)当对象引用计数归0时,ObjC給对象发送dealloc消息销毁对象

二、 iOS的内存管理规则

内存管理基本原则,总的来讲有三点:

1)当你通过new、alloc或copy方法创建一个对象时,它的引用计数为1,当不再使用该对象时,应该向对象发送release或者autorelease消息释放对象。
2)当你通过其他方法获得一个对象时,如果对象引用计数为1且被设置为autorelease,则不需要执行任何释放对象的操作;
3)如果你打算取得对象所有权,就需要保留对象并在操作完成之后释放,且必须保证retain和release的次数对等。

三、 经典内存泄漏及其解决方案

3.1 循环引用

3.2 循环中临时对象占用内存大

例子01:需要循环创建100000个学生对象来学习
 for (int i = 0; i < 10000; i ++) 
  {
         Student * s = [[Student alloc]init];
         [s study];
    }

  该循环内产生大量的临时对象,直至循环结束才释放,可能导致内存泄漏,解决方法和上文中提到的自动释放池常见问题类似:在循环中创建自己的autoReleasePool,及时释放占用内存大的临时变量,减少内存占用峰值。
  

for (int i = 0; i < 10000; i ++) 
{
         @autoreleasepool {
             Student * s = [[Student alloc]init];
             [s study];
         }
}

然而有时候autoReleasePool也不是万能的。

例子02:假如有2000张图片,每张1M左右,现在需要获取所有图片的尺寸,你会怎么做?

如果这样做

     for (int i = 0; i < 5000; i ++) 
     {
         CGSize size = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",i]].size;

     }

用imageNamed方法加载图片占用Cache的内存,autoReleasePool也不能释放,对此问题需要另外的解决方法。就是采用读文件和autoReleasePool结合的方式。

     for (int i = 0; i < 5000; i ++) 
     {
         @autoreleasepool {
             CGSize size = [UIImage imageWithContentsOfFile:filePath].size;

          }
     }
相关TAG标签
上一篇:ButterKnife的用法
下一篇:如何用MAC上的Safari检查iPhone手机App运行的Html页面
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站