OC的重点: 内存管理

1 基本原理

    OC的内存回收机制是和JAVA的自动回收机制是不同的,它有两种模式,或者准确的说是同
一种模式的两种不同体现,下面简单总结下.

1手动内存回收

      这是OC一直支持并在使用的内存回收机制,其主要实现和原理和C类似,遵循的是"谁使用,
谁回收"的原则.
      在OC中创建任何对象都会拥有一个类似于计数器的属性(使用 [对象 retainCount] 查看),
这个计数器是用来体现到底有多少个对象在使用这个对象(内存),当计数器为0的时候系统就
会调用delloc方法直接回收内存,以下几种方法都会对计数器产生改变:

alloc  让计数器从 0 变 1;

retain 计数器 +1;

copy 新开辟一块内存,把原对象的值复制;

release 计数器 -1;

autorelease 计数器延迟-1;

alloc 不再解释

retain :先看下面这段程序

        Person *p = [[Person alloc]initWithName:@"fds" age:12 sex:@"cfds"];
[p retain];
[p release];
[p release];

首先 alloc 计数器+1  = 1,retain一次,计数器再+1 = 2 ,release二次 -2  计数器 = 0 系统调用delloc

这样 这个对象才会正确的被释放掉

retain 又会牵扯到另一个问题,属性在Student类中定义了一个

@property (retain)Book *book;

- (void)setBook:(NSString *)book
{
if (_book != book) {
[_book release];
_book = [book retain];
}
}
- (NSString *)book
{
return [[_book retain] autorelease];
}

这是系统在定义book属性后默认给我们写的setter 和 getter的代码 ,首先看setter

当第一次为book赋值的时候

  [_book release];

由于_book为空 OC中对于一个为nil(null)的对象,它调用的任何方法都是无效的,所以执行

 _book = [book retain];

那么book的计数器为 2 这样的话 在外面创建book对象时 release一次 然后 当下一次赋值的时候

会把_book首先release一次  这样就会把本次的book释放掉,而且也符合谁使用,谁回收的原则,这样

也会产生一个问题,当Student释放时,最后一次的_book怎么释放

if 的作用是为了防止第二次赋值同一个值

这就牵扯到 delloc方法:

delloc方法,是当计数器为0的时候系统自动调用的,不会手动调用,一般都会改写这个方法,把本类中定义

过的所有对象类型的属性都release 一次,那么当student对象被回收时,所有调用的内存都被回收了.

copy: 

copy的使用也要牵扯到属性这个问题,

@property (copy)Book *book;

copy首先要实现NSCopy接口 实现里面的

- (id)copyWithZone:(NSZone *)zone方法 下面是一个Person类的例子

- (id)copyWithZone:(NSZone *)zone
{
Person *newPerson = [Person allocWithZone:zone];
[newPerson setAge:[self age]];
[newPerson setName:[self name]];
[newPerson setSex:[self sex]];
return newPerson;
}

这样就实现了copy出一个新对象的方法,调用 [person copy] 就可以了

那么对原对象或者现对象的操作都不会互相影响了

在调用 Person *p2 = [person copy]; 后 release p2 就能实现对象的回

收(p2 和 方法体内的 newPerson 指向的是同一个内存)  [ps: 又有一个知识点,指向同一个内存的指针无论有多少个,计数器都不会+1]

当person作为一个方法的属性时 setter和getter的方法如下

- (void)setPerson:(NSString *)person
{
if (_person != person) {
[_person release];
_person = [person copy];
}
}
- (NSString *)person

autorelease:

不自动释放 而是交给 autoreleasepool (延迟释放)自动释放池 : 讲对象所有权交给最近的NSAutoreleasepool 对象

[pool drain] 把释放池内的垃圾回收(一般不再使用)

[pool release] 把释放池都失去

原则上 尽可能用release

还有一个便利构造器的内存管理

+(id)personWithName:(NSString *)name age:(int)age sex:(NSString *)sex
{
Person *p = [[Person alloc ] initWithName:name age:age sex:sex];
return [p autorelease];
} { return [[_person retain] autorelease];}

这个也是使用了自动释放.

2自动管理内存(ARC ios5 新特性)

主要实现就是上面的autorelease, ARC模式是一种自动管理内存的模式,不用手动管理.

3内存泄露的几个情况

内存泄露 : 只开辟 不清除

过度释放: 释放之后还释放

野指针:  释放后 还在使用

补充一个@class

@class 声明一个类,主要用于.h文件中 让文件可以声明这个对象

等到用这个对象的方法时 再在.m 文件import

效果: 提高编译效率(不会因某个类改变导致编译器要重新编译所有关于这个类的文件)

这就是今天所学的了,感觉OC的内存管理是一个很是需要理解和下功夫的地方,它没有java的简便,

却提供了比较灵活的地方 内存管理的是OC里面一个重要的地方,需要大量的练习和使用.

oc 第五天(内存管理)的更多相关文章

  1. OC语言-05-OC语言-内存管理

    一.引用计数器 1> 栈和堆 栈 ① 主要存储局部变量 ② 内存自动回收 堆 ① 主要存储需要动态分配内存的变量 ② 需要手动回收内存,是OC内存管理的对象 2> 简介 作用 ① 表示对象 ...

  2. OC第七节——内存管理

    戏言: iOS开发已经到了一个ARC时代,一般不需要我们过多的去关注内存是怎么分配,怎么管理的.很长一段时间,我也不知道内存管理是什么鬼,但如果遇到这方面的问题,却找不到解决办法确实很头疼的.So,还 ...

  3. OC基础15:内存管理和自动引用计数

    "OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.什么是ARC? (1).ARC全名为A ...

  4. 七.OC基础加强--1.内存管理 2.野指针,内存泄露 3.set方法的内存管理 4.@property参数 5.@class和循环retain的使用 6.NSString的内存管理

    1,内存管理简单介绍 1,为什么要有内存管理? malloc selloc dealloc```需要回头复习 一般的内存 4s 是512m内存:6 是1024m内存: 当内存过大时,会耗尽内存.出现程 ...

  5. OC学习篇之---内存管理介绍和使用

    在之前的一片文章我们说了OC中谓词操作:http://blog.csdn.net/jiangwei0910410003/article/details/41923507,从今天开始我们就来看一下OC中 ...

  6. spark 源码分析之十五 -- Spark内存管理剖析

    本篇文章主要剖析Spark的内存管理体系. 在上篇文章 spark 源码分析之十四 -- broadcast 是如何实现的?中对存储相关的内容没有做过多的剖析,下面计划先剖析Spark的内存机制,进而 ...

  7. oc学习之路----内存管理

    直接上图啊.

  8. oracle 笔记---(五)__内存管理

    ###查看连接池的信息 select connection_pool,status,maxsize from dba_cpool_info            

  9. OC内存管理(MRC)

    首先说明一下几块存储区域: 栈区(局部变量.函数参数值) 堆区(对象.手动申请/释放内存) BSS区(未初始化的全局变量.未初始化的静态数据) 常量区(字符串常量以及初始化后的全局变量.初始化后的静态 ...

随机推荐

  1. Cookie机制和Session机制

    1. cookie 1. Cookie 是在HTTP协议下,服务器或脚本可以维护客户工作站上信息的一种方式.Cookie 是由 Web服务器保存在用户浏览器(客户端)上的小文本文件(内容通常经过加密) ...

  2. 简单的oracle sql语句练习

    简单的oracle sql语句练习 求每个部门的平均薪水 select deptno,avg(sal) from emp group by deptno 每个部门同一个职位的最大工资 select d ...

  3. c# 递归异步获取本地驱动器下所有文件

    //获取所有驱动器 string[] drives = Environment.GetLogicalDrives(); foreach (string driver in drives) { Cons ...

  4. 转:XSS知识大总结

    转:https://www.jianshu.com/p/75a3d9332b8c XSS知识大总结 2016.10.28 21:05* 字数 1332 阅读 961评论 2喜欢 13 XSS-即Cro ...

  5. Python并发编程-线程-一个简单的例子

    from threading import Thread import time def func(n): #子线程完成的 time.sleep(1) print(n) #多线程示例 for i in ...

  6. axio post 请求后端接收不到参数的解决办法

    原因是没有对参数进行序列化 默认情况下,axios将JavaScript对象序列化为JSON. 要以应用程序/ x-www-form-urlencoded格式发送数据. 在拦截器前修改 方法一,用原生 ...

  7. 【Leetcode】583. Delete Operation for Two Strings

    583. Delete Operation for Two Strings Given two words word1 and word2, find the minimum number of st ...

  8. debug id

    id是Eclipse的debugger自己生成的,用于告诉你哪些变量是指向同一个对象:id相同即指向同一个对象. primitive不是对象,所以就没有id. 但是如果你用primitive的wrap ...

  9. 初识JVM

    做了这么久的开发,到目前为止对JVM也只是一些简单的概念上的理解,正好周末于是将JVM的学习提上日程. JVM 概念 JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是 ...

  10. 【20181026T2】**图【最小瓶颈路+非旋Treap+启发式合并】

    题面 [错解] 最大最小?最小生成树嘛 蛤?还要求和? 点分治? 不可做啊 写了个MST+暴力LCA,30pts,140多行 事后发现30分是给dijkstra的 woc [正解] 树上计数问题:①并 ...