最近做项目,因为要求是非ARC环境,熟悉了ARC环境后,非ARC的要求却是一个小小的挑战,不过再怎么也是一个进步的方向,为此搜集了一些资料,整理了各位大神,前辈的心得,自己整理了一篇更基础的理解。

可以让一些文件保留ARC机制,一些文件不保留:
在Build Phases,在其中Complie Sorces中选择需要ARC的文件双击,并在输入框中输入:-fobjc-arc
如果不需要ARC则输入:-fno-objc-arc

基本原理认识(非ARC环境下):

1. Objective-C对象生成于堆之上,生成之后,需要一个指针来指向它。

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

2.Objective-C的对象在使用完成之后不会自动销毁,需要执行dealloc来释放空间(销毁),否则内存泄露。
[obj1 dealloc];

这带来了一个问题。下面代码obj2是否需要调用dealloc

ClassA *obj1 = [[ClassA alloc] init];
ClassA *obj2 = obj1;
[obj1 hello]; // 输出hello
[obj2 hello]; // 能够执行这一行和下一行吗?
[obj2 dealloc];

不能,因为obj1和obj2只是指针,它们指向同一个对象,[obj1 dealloc]已经销毁这个对象了,不能再调用[obj2 hello]和[obj2 dealloc]; 。 obj2实际上是一个无效指针。

3. Objective-C采用了引用计数(ref count或者retain coiunt)。对象的内部保存一个数字,表示被引用的次数。例如,某个对象被两个指针所(指向)引用那么它的retain count为2.需要销毁对象的时候,不直接调用dealloc真正销毁这个对象。

4. objective-C指针赋值时,retain count不会自动增加,需要手动retain。

【如果使用了add object或是set value进行赋值,则retain count只会增加直接引用的对象,间接引用的不会操作。也就是说只会对添加的对象计数加一,并不对内层的对象加1;】

  • 一个对象的dealloc方法若想被系统自动调用,前提是拴在此对象身上的狗链子已经全部消失,即retainCount为0.(在内存管理时,不建议去人工计算retainCount大小,来判断对象是否该释放了。应该使用对象“所有权”的思想去理解内存管理)。
  • 我们知道alloc \ copy \ retain 操作会让你个对象被一个指针持有。但是,大家往往忽略对象本身self的赋值,也会被一个指针持有。如下:
self.tableView.delegate = self;                     //让self被tableView.delegate 持有,需要显示release 
  • 如果一个对象被一个指针,通过 *** = self;持有,那么应该在合适释放比较合适呢。dealloc肯定不行,因为只有对象没有持有者时系统才会进dealloc。一般地,应该写在返回按钮或其它页面跳转事件中。

viewDidUnload与dealloc的区别 【它们两个没有任何关系】

其调用时机:

viewDidUnload:只有在收到内存警告后controller连着的主View被释放才会调用。

dealloc:由系统中类销毁或是内存不足时调用,因为系统知道类何时被销毁,一般为一个对象的retainCount为0时,系统会自动调用dealloc将这个对象进行销毁。

// 更多参见:
Advanced Memory Management Programming Guide

个人理解:

当我们不想再引用这个对象时就可以使用release来释放将这个对象的引用减1,去调用release方法。当我们传值给一个方法时,其实接收的参数只是一个指针,我们要做的是将传过来的同样类型的指针地址赋值过来,这样它们拥有的是同样的一个对象,如果我们使用一个新的指针指向这个对象(赋值)那么我们就可以将参数进行一次release,不过此时要记得将这个新的指针指向的对象retain一下。这样才能保证使用正常。

对于导航控制器对象的release,我们Push或是pop时需要放到哪个位置呢,一般来说需要将其写在返回按钮或其它页面跳转事件中。

ViewController *A = [ViewController alloc] init];
[self.navigationController pushViewController:A animated:YES];
[A release];

这时我们就需要将A控制器进行一次release,因为导航控制器已经将其加入到navigation controller栈中也就是说已经对其进行了引用,这时,A已经不需要对所指身的对象有所有权了,就可以将其release掉了。

口诀与范式:

1. 谁创建,谁释放(你使用alloc,copy,retain一个对象,你就要在不使用时release或autorelease一下,不是你创建的,你就不需要去释放)
解释:你在一个函数中alloc生成了一个对象,且这个对象只在这个函数中被使用,那么你就必须在这个函数中调用release或autorelease。如果你在一个class的某个方法中alloc一个成员对象,且没有调用autorelease,那么你需要在这个类的dealloc方法中调用release;如果调用了autorelease,那么在dealloc方法中什么都不需要做。

2. 除了alloc、new、copy之外的方法创建的对象都被声明了autorelease。

3. 谁retain,谁release。只要你调用了retain,无论这个对象是如何生成的,你都要调用release。有时候你的代码中明明没有retain,可是系统会默认在实现中加入retain。(这点比较含糊,苹果官方文档并不有明确表明)
release与nil,我们在release一个对象时要立即把指针清空(顺便说一句,release一个空指针是合法的,但不会发生任何事情[obj1 release]; obj1 = nil); //只是将这个指针所指向的对象的retainCount-1,然后将这个指针指向nil,因为指向了nil这个指针如果release的话是不会出现问题的。

3. 指针赋值给另一个指针

ClassA *obj2 = obj1;
[obj2 retain]; // do something
[obj2 release];
obj2 = nil;

4. 在一个函数中创建并返回对象,需要把这个对象设置为autorelease。

ClassA *Func1() {ClassA *obj = [[[ClassA alloc] init] autorelease];return obj;
}

5. 如果重写dealloc方法切记要在其中调用基类的dealloc

-(void)dealloc {...[super dealloc];
}

6. 在一个class中创建和使用property
6.1 声明一个成员变量。 ClassB *objB;

6.2 使用property,加上retain参数;

6.3 定义property@synthesize objB;

6.4. 除了dealloc方法以外,始终用点(.)操作符的方式来调用property  self.objB或者objA.objB;

6.5 在dealloc方法中release这个成员变量[objB release];

6.6 在给这个property赋值时,有手动release和autorelease两种方式;

// 第6.2点与第6.3点,因为在使用 retain 和 @synthesize objB时自动会在set方法中

if (objB != value) {[objB release];objB = [value retain];
}

所以我们需要在dealloc方法中release这个成员变量。

- (void)dealloc{[objB release];[super dealloc];
}

7.如果只是使用类拓展声明了变量,如果将一个指针赋值给它需要记住retain一下(符合使用规则),在使用最终的dealloc方法中,记得将成员变量release一下。至于传过来的指针,其在上一个方法中建议使用autorelease方法,或者调用release方法,非copy alloc 方法来创建对象。

内存管理基本原理及非ARC环境使用小心得相关推荐

  1. OC 知识:彻底理解 iOS 内存管理(MRC、ARC)

    1. 什么是内存管理 程序在运行的过程中通常通过以下行为,来增加程序的的内存占用 创建一个OC对象 定义一个变量 调用一个函数或者方法 而一个移动设备的内存是有限的,每个软件所能占用的内存也是有限的 ...

  2. 内存管理(二) ARC

    内存管理(二) ARC 上篇我们介绍了MRC,本篇我们介绍下ARC ARC概述 ARC是一种编译器功能,它通过LLVM编译器和Runtime协作来进行自动管理内存.LLVM编译器会在编译时在合适的地方 ...

  3. OC之非ARC环境下循环retain问题

    观察上述情况,上述就是著名的循环引用问题,对于此类问题,"你包含我,我包含你",里面相关的对象占用的内存永远回收不了,解决办法很简单,与常规方法不同.正常情况下,我们应在Perso ...

  4. ARC内存管理机制详解

    ARC在OC里面个人感觉又是一个高大上的牛词,在前面Objective-C中的内存管理部分提到了ARC内存管理机制,ARC是Automatic Reference Counting-自动引用计数.有自 ...

  5. iOS内存管理策略和实践

    来源:http://www.baidu.com/link?url=irojqCBbZKsY7b0L2EBPkuEkfJ9MQvUf8kuNWQUXkBLk5b22Jl5rjozKaJS3n78jCnS ...

  6. OC内存管理常见面试题整理

    1:简述OC中内存管理机制.与retain配对使用的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?readwrite,rea ...

  7. iOS经典面试题总结--内存管理

    内存管理 1.什么是ARC? ARC是automatic reference counting自动引用计数,在程序编译时自动加入retain/release.在对象被创建时retain count+1 ...

  8. 初探swift语言的学习笔记六(ARC-自动引用计数,内存管理)

    作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/31824179 转载请注明出处 如果觉得文章对你有所帮助,请通过留言 ...

  9. iOS内存管理—MRC

    文章目录 预备知识 手动引用计数MRC 自己生成的对象,自己持有 非自己生成的对象,自己也能持有 不再需要自己持有的对象时释放 无法释放非自己持有的对象 @property参数 MRC中避免循环ret ...

  10. Linux内存管理基础

    系统启动之Linux内存管理基础 Keywords 非一致内存访问(NUMA)模型.节点(node).内存管理区(Zone).一致内存访问(UMA)模型.内核页表.内存管理区分配器(伙伴系统Buddy ...

最新文章

  1. http://blog.51cto.com/wbb827/1175634
  2. VC6中编译参数设置
  3. JavaScript之Style属性学习
  4. JavaScript事件绑定
  5. pay-as-you-go
  6. 工作65:导航栏使用
  7. Python的贝叶斯网络学习库pgmpy介绍和使用
  8. html radio 更换图片,html修改radio、checkbox样式
  9. C语言学习笔记---位字段
  10. 网络安全:9次实验带你学会网安
  11. [笔记] 《Windows网络编程(第2版)》
  12. STM32_编程入门
  13. 怎样使用Scanner(扫描仪),超级详细,不容错过!!!
  14. 完美解决电脑老是弹出广告窗口!
  15. Linux 系统 /var/log/journal/ 垃圾日志清理
  16. Qtcreator远程调试arm开发板程序指南
  17. 论文笔记|固定效应的解释和使用
  18. Leetcode 1436旅行终点站 拓扑排序 并查集与队列
  19. Python之数据分析总结
  20. IDE硬盘 SCSI硬盘 SATA硬盘

热门文章

  1. 灵感分享|10个优秀网站设计实例赏析及原型分享
  2. sqllabs详解与知识点汇总(内含代码审计)
  3. HAMA 混合信道接入Ad-Hoc,分布式TDMA 协议
  4. 安全策略篇 安全策略发展历程详解
  5. 天原笔记(3)气旋与反气旋
  6. 完美解决虚拟机占用硬盘越来越大、删除快照无效、菜单栏显示不全等问题
  7. oracle数据库学习笔记(二)(创建表、DDL、DML、单行插入数据、多行插入数据)
  8. IBM Tivoli Storage Manager安装介绍
  9. Web前端零基础入门HTML5+CSS3学习笔记补充
  10. Bootloader和Linux启动过程总结