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. LoadRunner中自定义C函数实现字符串替换

    .在globals.h 中定义一个函数ReplaceStr,实现字符串的替换: int ReplaceStr(char* sSrc, char* sMatchStr, char* sReplaceSt ...

  2. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) E - Goods transportation 最大流转最小割转dp

    E - Goods transportation 思路:这个最大流-> 最小割->dp好巧妙哦. #include<bits/stdc++.h> #define LL long ...

  3. ref:PHP反序列化漏洞成因及漏洞挖掘技巧与案例

    ref:https://www.anquanke.com/post/id/84922 PHP反序列化漏洞成因及漏洞挖掘技巧与案例 一.序列化和反序列化 序列化和反序列化的目的是使得程序间传输对象会更加 ...

  4. 转:Exploiting Electron RCE in Exodus wallet

    转:https://hackernoon.com/exploiting-electron-rce-in-exodus-wallet-d9e6db13c374 Exploiting Electron R ...

  5. 转:LNMP虚拟主机PHP沙盒绕过/命令执行(php exec命令被禁之后)

    LNMP虚拟主机PHP沙盒绕过/命令执行 lnmp更新1.2版本,很多东西都升级了,很棒.不过还是发现一个BUG. LNMP是一款linux下nginx.php.mysql一键安装包. 下载:http ...

  6. GIT修改邮箱

    git报错-->! [remote rejected] master -> master (push declined due to email privacy restrictions) ...

  7. 洛谷——P1894 [USACO4.2]完美的牛栏The Perfect Stall

    P1894 [USACO4.2]完美的牛栏The Perfect Stall 题目描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星 ...

  8. poj2531(深搜剪枝)

    题意就是把节点分成A.B两组,节点间距C给了,要求解分组的方法,使得∑Cij (i∈A,j∈B)最大. 首先把所有节点都放在一组,然后采用深度优先搜索的方法,对每一个节点都做判断是否应该移到另一组去, ...

  9. 【BZOJ】1042: [HAOI2008]硬币购物

    1042: [HAOI2008]硬币购物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3307  Solved: 2075[Submit][Stat ...

  10. mySql---logback日志写入数据库(mysql)配置

    如题  建议将日志级别设置为ERROR.这样可以避免存储过多的数据到数据中. 1  logback 配置文件(如下) <?xml version="1.0" encoding ...