`
izuoyan
  • 浏览: 9265842 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

IOS内存管理

 
阅读更多
IOS内存管理

很多童鞋对于IOS中的内存管理处理的不好,有时候感觉自己已经掌握了,其实用起来的时候往往出现很多的内存泄露或者因为内存管理的不恰当导致程序崩溃!
网上有一片很详细的内存管理文章,很多人估计嫌长,不愿意去看,我就写一个简单易懂的分享。
我分四块来讲解,这篇文章比较简单,因为我不想把你们搞晕,其实总的来说就一个原则!
一、IOS内存管理的机制
IOS中没有垃圾回收机制(IOS5中好像已经有了,但是目前还不太实用),所以基本一切都是自己手动管理。
IOS中采用引用计数的内存管理方式,啥意思呢?讲的通俗点就是说一块内存地址是否应该被释放是又retaincount来决定的,如果这块内存地址的retaincount为0,那么这块内存就会被释放,再也找不到了。
所以想让他一直存在,那么它的retaincount就必须大于0。
那么如何管理呢?其实原理非常简单,就是谁用谁retain,谁retain的谁release,遵循这个原则的目的就是让你不会出错。
举个例子

ClassA *obj1 = [[ClassA alloc] init];

这里你申请了一块内存地址,指针obj1指向了这块内存地址,同时你给它retain了一下(retain,copy,alloc这几个方法都相当于把retaincount加一),此时obj1所指向的这块内存地址retaincount为1。
接着来(这里我只是举例子让大家了解一下,这些代码没有什么实际意义)
    ClassA *obj2=obj1;
    [obj2 retain];

    好了,大家看一下,obj1和obj2同时都指向了上面所述的内存地址,我假设这块内存为A,那么A这块内存的retaincount为2。
    假如大家在之后一直在使用obj1和obj2,最后不用的时候,需要释放了,我希望大家这样来释放

    [obj1 release];
    [obj2 release];

    而不希望大家这样来释放
      [obj1 release];
      [obj1 release];
      //或者
      [obj2 release];
      [obj2 release];

      为什么这样呢?上面两种释放方法没有错,都成功将A这块内存的retaincount减为0,导致A被释放了。但是你没有遵循以上所说“谁用谁retain,谁retain的谁release”。
      这只是一个小例子,你可能感觉不到问题的严重性,如果你做一个项目,在其中有大量这种retain,release的话,你不遵循这种原则,你会死的很惨,没有条理最后你会被搞的很乱,找都找不到。
      二、不要随便看到retaincount多就给它释放
      很多朋友在学完内存管理后喜欢玩消除,不该释放的他去释放,举个例子

      UIViewController *ct1=[[UIViewController alloc] init];[self.navigationcontroller pushViewController:ct1 animated:YES];[ct1 relese];

      这里,初始化一个viewcontroller,然后用导航push进来,最后释放这个viewcontroller,很多人在这里操作完毕后,继续打印ct1的retaincount,发现它的retaincount不为0,就继续release,这里是非常错误的方法,直接导致程序崩溃,继续看以上原则“谁用谁retain,谁retain的谁release”,你用的时候,初始化,并retain了一次,最后你release了一次,到此结束!之后不管你发现它的retaincount为几,你都不该再release。你打印出来的retaincount并不是你retain的,而是系统框架本身retain的,由框架本身来处理,开发者不必理会。
      类似还有很多,数组的addobject、addsubview等等很多方法,都是框架自己家retain的,开发者本身retain后release,不必理会它的retaincount。
      另外插一句,如果是多人协同开发,这种情况最容易碰到,别人传递一个参数过来,你拿过来retain后使用,使用完毕release,发现retaincount还不是0,于是你继续release,这样你就把你同伴retain的计数给release掉了,当他下次使用的时候发现崩溃了,这种情况会让你的团队浪费无数的时间来找原因。

      三、关于属性
      属性在.h文件中是这样声明的

      @property(nonatomic,retain) Class *obj;

      括号内第二个参数代表的意义是什么呢?
      我们分析一下他内部的机制
      @property (retain) Class* obj;@synthesize obj;实际上是gettersetter,有retain参数的property,内部代码如下

      -(Class *) getObj
      {
      return obj;
      }


      -(void) setObj:(Class *) value
      {
      if (obj != value)
      {
      [obj release];
      obj = [value retain];
      }
      }

      愿意仔细分析的童鞋可以仔细研究一下,不太明朗的童鞋请听我说。
      这个属性定义以后如何使用呢?我们只说赋值(也就是set)
      self.obj=xxx;
      [self setObj:xxx];
      obj=xxx;
      赋值方法有以下几种,其中前两个是相同的,都是调用了setObj:方法同时也就导致了obj的retaincount增加了1,而第三个赋值方法并没有增加retaincount,只是将指针指向了xxx内存地址。
      所以大家赋值时可以这样
      Class *c=[[Class alloc] init];
      self.obj=c;[c release];
      或者Class *c=[[Class alloc] init];
      [self setObj:c];[c release];
      或者Class *c=[[Class alloc] init];obj=c;

      属性的这个机制是让你在整个self里(也就是当前类的实例里)一直保留这个obj的retaincount,所以你必须在此类的dealloc里将obj的retaincount置零(你只需要release,如果你严格遵守“谁用谁retain,谁retain的谁release”的话)
        -(void)dealloc
        {
        [obj release];
        [super dealloc];
        }


        这里,其实我主要要说明的就是属性的赋值方式用self.xxx=xxxx和xxx=xxxx是完全不同的赋值方式,大家切记!
        四、autorelease对象
        autorelease对象就是自动释放对象,大家可能会疑惑,能自动释放,我还管理干嘛,我都用自动释放算了,事实不是这样的,自动释放确实好用,但是自己管理内存才能让项目占用更小的资源,跑起来更流畅,大家可以手动管理加autorelease一起来使用,我先讲解一下autorelease对象到底是什么个情况。
        首先,告诉大家autorelease对象什么时候才会被释放。
        在main函数里有一个autorelease pool,自动释放池,所以在这个自动释放池里的autorelease对象都会在自动释放池结束的时候全部被释放。
        大家可能会问了,“难道所有的autorelease对象都是在程序退出的时候才被释放?”,答案当然不是,其实main函数中只是一个程序中众多自动释放池中的一个,每个runloop都会隐性的创建一个自动释放池,啥是一个runloop?每个UIView创建、delegate回调等等都会创建一个自动释放池,记得这个“等等”,意思就是有很多(如果大家想要详细了解runloop,可以去google)。所以大家不用担心autorelease对象不会被释放。
        很多系统的方法,比如[NSArray array]、[NSString stringformat]等等返回的对象都是autorelease对象,这些对象是不需要手动释放的,如果手动释放会导致程序崩溃!切记!,原则就是系统中所有没有使用alloc、copy、retain来创建的对象都是autorelease对象,大家千万别手动release!


        好了,就说这么多吧,如果有什么错误,希望大家提出,我来改。。。工作太忙,也没啥时间写的更详细!!!望大家见谅!
        分享到:
        评论

        相关推荐

          庄延军《iOS内存管理及优化》

          庄延军所著的《iOS内存管理及优化》是一本专注于iOS平台内存管理技巧与性能优化的书籍。它旨在帮助读者深入理解iOS内存管理机制,掌握内存优化方法,从而提升应用性能、稳定性和用户体验。 内存管理是移动应用开发...

          iOS内存管理1

          iOS内存管理1 iOS内存管理是iOS开发中非常重要的一部分,主要是为了避免内存泄露和循环引用。iOS内存管理有两种方式,一种是 Manual Reference Counting(MRC),一种是 Automatic Reference Counting(ARC)。 ...

          IOS内存管理与软件调试

          首先,我们来谈谈iOS内存管理。iOS系统采用自动引用计数(Automatic Reference Counting, ARC)作为主要的内存管理机制。ARC负责跟踪对象的所有者,并在适当的时候释放不再使用的内存。理解如何正确使用ARC至关重要...

          ios内存管理之深浅拷贝

          本文将深入探讨iOS内存管理中的一个重要概念——深浅拷贝,以及与其相关的`retain`、`copy`和`retainCount`。这些概念对于理解Objective-C中的内存管理机制至关重要。 首先,我们需要了解iOS内存管理的基本原则,即...

          iOS高级内存管理ARC模式手动模式英文文档含示例工程

          标题中的"iOS高级内存管理ARC模式手动模式英文文档含示例工程"表明,这个压缩包提供了深入探讨iOS内存管理的资源,包括了ARC和非ARC(即手动内存管理)的相关内容。这可能包括如何在ARC环境下处理特殊情况,以及何时...

          小议iOS内存管理-中文.pdf

          ### iOS内存管理核心知识点 #### 一、前言与背景 在探讨iOS内存管理之前,有必要理解为何这一主题如此重要。对于从C++或Java转向Objective-C(简称OC)的开发者来说,OC语言的特性显得既独特又挑战性十足。与Java...

          iOS内存管理方面的面试题汇总

          在iOS开发中,内存管理是...总之,理解并熟练掌握这些iOS内存管理的知识点,对于编写高效、稳定的应用至关重要。在面试中,能深入讨论这些问题,不仅体现了开发者的专业技能,也显示了其对程序性能优化的关注和重视。

          ios开发内存管理

          ios移动开发的内存管理ppt,讲的不错,你值得拥有

          iOS 内存管理机制 详细解读

          放入栈中。此区域的内存由编译器...了解并掌握内存管理是开发iOS应用的关键,合理的内存管理能确保应用的性能和稳定性。无论是手动的MRC还是自动的ARC,都需要开发者对内存管理有深入的理解,防止内存泄漏和意外崩溃。

          IOS高级内存管理编程指南.pdf

          本文将详细介绍iOS内存管理的知识点,包括内存管理的基本概念、策略、最佳实践和实战技巧,以及Autorelease池的使用等。 ### 1. 内存管理概述 内存管理是指在程序运行时对内存进行分配、使用和释放的过程。在...

          IOS内存管理Delegate与IOS下Speex语音压缩开发

          IOS的内存管理详解。 Delegate具体详解,使用流程。 Speex的语音压缩技术。 完整详细解读。40页,通俗简单,深入浅出,并有代码示例ppt。

          ios memory 内存管理

          ### iOS内存管理的核心概念 #### ARC (Automatic Reference Counting) ARC是苹果在iOS 5中引入的一项技术,用于自动管理对象的引用计数,从而避免了手动管理内存带来的复杂性和错误。通过ARC,编译器能够自动插入...

          UnityAndroid/iOS查看真机内存使用情况插件

          2. **Android和iOS内存管理**:Android和iOS操作系统都有自己的内存管理机制。Android使用Dalvik或ART虚拟机进行内存分配和回收,而iOS则依赖于Objective-C/Swift的自动引用计数(Automatic Reference Counting, ARC)...

          ios内存管理

          iOS开发有关object-c内存管理!

          详解关于iOS内存管理的规则思考

          iOS内存管理的核心在于引用计数(Reference Counting)机制,这是Objective-C中的基础概念。当对象的引用计数为0时,系统会自动回收该对象的内存。本文将深入探讨iOS内存管理的规则及其背后的思考。 1. **生成并...

          cz-add#iOS_maker#iOS 内存管理总结1

          3.未初始化数据:末初始化的全局变量、静态变量等 1.对字符串,字典,数组进行mutableCopy操作,属于深拷贝,并且会生成一个新的可变对象 2.对可变字符

          iOS内存管理中引用计数的学习

          本文主要讨论的是iOS内存管理中的引用计数机制,这是Objective-C和Swift(早期版本)中的一种自动内存管理策略。 引用计数是一种跟踪和管理对象生命周期的方法。简单来说,一个对象的引用计数表示了有多少个指针...

          iOS内存管理

          强引用、弱引用 weak和strong只有你打开ARC时才会被要求使用

        Global site tag (gtag.js) - Google Analytics