与 C 有一点类似,oc  需要使用 alloc 方法申请内存。不同的是,c 直接调用 free 函数来释放内存,而 oc 并不直接调用 dealloc 来释放。整个  oc 都使用对象引用,而且每一个对象都有一个引用计数器。当计数器为 0 时,系统调用 dealloc 来释放内存。oc 提供了 autorelease 属性,从而可以让系统自动释放对象所占有的内存。

  1. 基本的内存管理

  因为 iPhone 运行环境没有垃圾回收机制,所以我们在为它开发一个应用程序的时候需要了解一些基本的内存管理方面的做法。

  申请内存:(alloc)

  当使用 alloc 创建了一个对象时,需要在用完这个对象后释放 (release)它,但如果该对象已经被设置为自动释放(autorelease)类型,则无需再去释放它,否则程序会报错。

  释放内存 (dealloc)

  当一个对象从内存上删除之前,系统就自动调用 dealloc 方法,这是释放成员变量的内存的最好时机,比如释放前面 alloc 的 name 和 address.

  

 - (void)dealloc
{
[name release]; // 释放成员变量所占的内存
[address release]; // 同上
[super release]; // 这个非常重要,因为必须调用这个方法来让父类清除它自己,否则,这个对象将没有被清除干净,会造成内存泄漏。
}

  在垃圾回收机制下, dealloc 不会被调用到,取而代之的是,需要实现 finalize 方法。

  引用记数 (retainCount)

  

  整个 oc 都使用对象引用,而且每个对象有一个引用计数器。当使用 alloc (或者 copy)方法创建一个对象时,其计数器的值为1。调用 retain 方法就增加 1,调用 release 方法就减少1。当计数器为0时,系统自动调用 dealloc 方法来释放内存中的对象。下面看一个实际的例子:

  

 #import <Foundation/Foundation.h>
#import "Person.h" int main() {
Person *p = [[Person alloc] init]; // 计数器的值默认为1.
int i1 = (int)[p retainCount]; // i1 = 1.
NSLog(@"i1 = %ld",i1); [p retain]; // 计数器的值加1变为2.
[p release]; // 计数器的值减1变为1.
[p release]; // 计数器的值减1变为0,系统自动调用 dealloc 方法来释放内存中的对象。
return ;
}

  字符串的处理

  如果alloc 或者 copy 了一个对象(比如字符串),那么,在方法结束的时候需要 release 或者 autorelease 这个对象。

  

  类成员变量的处理

  

  

  内存泄漏

  为防止内存泄漏:我们必须遵循下面几个内存管理的基本原则:

  1. 如果使用 alloc (或者 copy)方法创建一个对象,或者使用 retain 保留一个对象,那么,都要自己释放对象。

  2. 在大多数情况下,申请内存的语句数量和释放内存的语句数量应该相等。

  3. 尽量少使用内存,用完后立即释放。

  垃圾回收 (Garbage-collection)

  

  copy , nonatomic

  

  对于字符串类型的属性变量,我们经常使用下面类似的语句:

  @propery (nonatomic,copy) NSString *name; 它就等价与

  

 

    现在新的 Xcode 版本中已经不需要我们人工去管理内存了,而是引用了ARC 内存管理机制:

  

对于ARC机制的使用,苹果发布了几条重要的规则需要开发者遵守。单单看那些生搬硬套的东西难免生涩,根据开发经验将规则总结如下:

(1)不能调用dealloc,不能重写和调用retain,release,retainCount 和autorelease,同理,@selector(retain),@selector(release)这些曲线救国的方法也不能调用。 dealloc虽然能够重写,但是不能调用[super dealloc]之类的方法,CoreFoundation框架由于非从属cocoa框架,所以CFRetain和CFRelease仍然正常使用。

(2)不能使用NSAllocateObjec或NSDeallocateObject函数来创建对象

(3)不能在C语言的结构体中使用对象指针,同时建议用object-c的类来管理数据而不是结构体

(4)不得使用NSAutoreleasePool对象。ARC中,全部使用@autorelease关键字代替,且比NSAutoreleasePool更高效

(5)不得使用内存Zone,那些牵涉NSZone的方法都不得使用。

(6)不得对一个属性变量的取值方法命名以new开头

(7)outlet均用weak关键字修饰,除非他是xib中最顶部的界面元素,则需要strong。

(8)Core Foundation不适合ARC,该创建的仍创建,该释放的仍释放。

  

 ARC新增关键字

ARC新增两个武功高强的左右护法:strong 和 weak

strong的含义和retain相同,weak和assign相同,修饰完的属性变量用法也是完全没有改变,不过strong和weak只能修饰对象。

苹果官方对于ARC机制中对象的内存引用规则:

(1)任何对象,如果仍有持有者,就不会销毁

(2)任何对象,已经没有任何持有者,即自动销毁

持有者就是指向对象的指针,如果是strong修饰的,即是对象的持有者,如果是weak属性的,则不是持有者。

Objective-c 内存管理的更多相关文章

  1. Objective C内存管理之理解autorelease------面试题

    Objective C内存管理之理解autorelease   Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的A ...

  2. Objective C 内存管理[转]

    1  配对原则 alloc – release new – release retain - release copy – release 2  new和alloc-init的区别 (1)区别只在于a ...

  3. objective C 内存管理及属性方法具体解释

    oc为每一个对象提供一个内部计数器.这个计数器跟踪对象的引用计数,当对象被创建或拷贝时.引用计数为1.每次保持对象时,调用retain接口.引用计数加1.假设不需要这个对象时调用release,引用计 ...

  4. Objective -C Memory Management 内存管理 第一部分

    Objective -C Memory Management  内存管理  第一部分 Memory management is part of a more general problem in pr ...

  5. Objective-C(内存管理)

    引用计数器 每个OC对象都有一个占4个字节存储空间的引用计数器 当使用或创建一个对象时,新对象的引用计数器默认是1 retain:可以使引用计数器+1 release:可以是引用计数器-1 retai ...

  6. Objective C----手动管理内存和自动管理内存

    对象的引用计数(Reference Counting) 正常情况下,当一段代码需要访问某个对象时,该对象的引用的计数加1:当这段代码不再访问该对象时,该对象的引用计数减1,表示这段代码不再访问该对象: ...

  7. IOS学习笔记3—Objective C—简单的内存管理

    今天简述一下简单的内存管理,在IOS5.0以后Apple增加了ARC机制(Automatic Reference Counting),给开发人员带来了不少的方便,但是为了能更好的理解IOS内存管理机制 ...

  8. objective-c(内存管理)

    本文主要记录objective-c 内存管理的知识点: 1.objective-c的对象都是分配内存在堆上,与C的mallock和C++的new类似,只有int等系统变量分配内存在栈上: 2.obje ...

  9. iOS学习17之OC内存管理

    1.内存管理的方式 1> iOS应用程序出现Crash(闪退),90%的原因是因为内存问题. 2> 内存问题 野指针异常:访问没有所有权的内存,如果想要安全的访问,必须确保空间还在 内存泄 ...

  10. iOS - OC 内存管理

    1.OC 基本内存管理模型 1.1 自动垃圾收集 在 OC 2.0 中,有一种称为垃圾收集的内存管理形式.通过垃圾收集,系统能够自动监测对象是否拥有其他的对象,当程序执行需要空间的时候,不再被引用的对 ...

随机推荐

  1. org/apache/commons/pool/impl/GenericObjectPool异常的解决办法

    org/apache/commons/pool/impl/GenericObjectPool异常的解决办法 webwork+spring+hibernate框架的集成, 一启动Tomcat服务器就出了 ...

  2. Hibernate 数据的批量插入、更新和删除

    4.2  Hibernate的批量处理 Hibernate完全以面向对象的方式来操作数据库,当程序里以面向对象的方式操作持久化对象时,将被自动转换为对数据库的操作.例如调用Session的delete ...

  3. sqoop安装与使用

    sqoop简介 sqoop名字是怎么来的?Sqoop: SQL-to-Hadoop 连接传统数据库和hadoop的桥梁,把关系型数据库的数据导入到hadoop系统(如HDFS,HBASE和hive中) ...

  4. 音乐ID3 中 专辑封面解析(APIC帧)

    ID3V2 中 APIC 帧标识 专辑封面.前几天 百度 谷歌 都没有找到具体的说明.有点小伤人. 最好参考  Android 中的 id3.cpp 以及一个java 开源 id3 库.找到这里的规格 ...

  5. HDU 3641 Treasure Hunting(阶乘素因子分解+二分)

    题目链接:pid=3641">传送门 题意: 求最小的 ( x! ) = 0 mod (a1^b1*a2^b2...an^bn) 分析: 首先吧a1~an进行素因子分解,然后统计下每一 ...

  6. 从零开始nodejs系列文章

    http://blog.fens.me/series-nodejs/ 从基础的node安装到npm配置,从express到jade,还有mongoDB.是一个很好的node教程

  7. json中头疼的null

    在服务器返回 json 数据的时候,时常会出现如下数据 "somevalue":null 这个时候,json 解析的时候,就会吧这个 null 解析成 NSNull 的对象,我们向 ...

  8. Android 利用摄像头指尖测试心率

    过摄像头来获得心率,搜了一下这个技术真不是噱头,据说在iPhone早有实现,主要原理是:当打开软件时,手机的闪光灯也会被自动打开,用户将手指放在摄像头上时,指尖皮下血管由于有血液被压入,被光源照射的手 ...

  9. C语言与管道

    int main() { int s; int n; float avg; scanf("%d,%d",&s,&n); //特别注意的地方 // scanf(&qu ...

  10. 【转】jsp 表单form传值

    写的很好,看到了忍不住不转啊,希望可以分享一下~~ 转载自http://blog.csdn.net/anmei2010/article/details/4140216 页面间链接和数据传递的三种方式 ...