1. 在每个OC对象内部,都专门有8个字节的存储空间来存储引用计数器。
  2. 引用计数器的常见操作
  3. retain消息:堆内存中对象的计数器变量 +(该方法返回对象本身,要想计数器变量加1就要调用对象的retain方法)
  4. release消息: 堆内存中对象的计数器变量 -(不代表释放对象,要想计数器变量减1就要调用对象的release方法)
  5. retainCount:获得对象当前的应用计数器值,输出:%ld %lu,NSLog(@"%lu",h.retainCount);
  6. 注意:release不代表销毁对象,仅仅是引用计数器-
  7.  
  8. .谁创建,谁release
  9.  
  10. )如果你通过alloc,new,copy来创建了一个对象,那么你就必须调用release或者 autorelease方法.
  11. )不是你创建的就不用你去负责
  12. .谁retain,谁release
  13.  
  14. 只要你调用了retain,无论这个对象时如何生成的,你都要调用release
  15.  
  16. )对象的销毁
  17.  
  18. 1个对象的应用计数器为0时,那么它将被销毁,其占用的内存被系统回收。
  19. 当对象被销毁时,系统会自动向对象发送一条dealloc消息。一般会重写dealloc方法,在这里释放相关的资源,dealloc就像是对象的“临终遗言”。
  20. 一旦重写了dealloc方法,就必须调用[super dealloc],并且放在代码块的最后调用。
  21. 注意:不能直接调用dealloc方法。
  22. 一旦对象被回收了,那么他所占用的存储空间就不再可用,坚持使用会导致程序崩溃(野指针错误)
  23.  
  24. 注意;
  25.  
  26. ) 如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收(除 非整个程序已经退出 )
  27. )任何一个对象,刚生下来的时候,引用计数器都为1。(对象一旦创建好,默认引用计数器就是1)当使用allocnew或者copy创建一个对象时,对象的引用计数器默认就是1.
  28.  
  29. 、内存管理的分类
  30.  
  31. Objective-C提供了三种内存管理方式:
  32.  
  33. .MannulReference-Counting(MRC,手动管理,在开发iOS4.1之前的版本的项目时我们要自己负责使用引用计数来管理内存,比如要手动 retainreleaseautorelease 等,而在其后 的版本可以使用 ARC,让系统自己管理内存。)
  34. .automatic reference-counting(ARC,自动引用计数,iOS4.1之后推出的)
  35. .garbage collection(垃圾回收)。iOS不支持垃圾回收;
  36.  
  37. ARC作为苹果新提供的技术,苹果推荐开发者使用ARC技术来管理内存;
  38.  
  39. 开发中如何使用:需要理解MRC,但实际使用时尽量用ARC

Gamer.h

  1. #import <Foundation/Foundation.h>
  2. #import "House.h"
  3.  
  4. @interface Gamer : NSObject
  5. {
  6. House *_house; // 房间,游戏玩家在哪里房间
  7. }
  8. - (void)setHouse:(House *)house;
  9. - (House *)house;
  10. //@property House *house;
  11. @end

Gamer.m

  1. #import "Gamer.h"
  2.  
  3. @implementation Gamer
  4. - (void)dealloc
  5. {
  6. NSLog(@"玩家被释放");
  7. // 当玩家自己被回收时,对房间进行一次release操作减少堆内存中对象的计数器变量值.
  8. [_house release];
  9. [super dealloc];
  10. }
  11.  
  12. - (void)setHouse:(House *)house
  13. {
  14. if (_house != house) {
  15. //当玩家换房间时,需要对旧房间做一次release操作减少堆内存中对象的计数器变量值
  16. [_house release];
  17. // 玩家要进入房间,玩家就要对房间进行一次retain操作增加堆内存中对象的计数器变量值.
  18. _house = [house retain];
  19. }
  20. }
  21. - (House *)house
  22. {
  23. return _house;
  24. }
  25. @end
  26.  
  27. /*
  28. // 1、创建玩家对象
  29. Gamer *game = [[Gamer alloc] init];
  30. // 2、创建房间对象
  31. Room *room = [[Room alloc] init];
  32. // 3、让玩家进入房间
  33. game.room = room;//堆中对象的计数器变量没有加1因为没有调用retain方法,
  34. // 4、释放房间对象
  35. [room release];
  36. // 5、输出玩家的房间
  37. NSLog(@"玩家的房间是:%@",game.room);
  38. 此时,会报野指针错误。
  39.  
  40. 解决方案:
  41. ,对房间进行一次retain。
  42. // 声明类
  43. @interface Gamer : NSObject
  44. {
  45. Room *_room;
  46. }
  47. - (void)setRoom:(Room *)room;
  48. - (Room *)room;
  49.  
  50. // 实现类
  51. @implementation Gamer
  52. - (void)setRoom:(Room *)room
  53. {
  54.  
  55. [room retain];//堆中对象的计数器变量加1后赋值
  56. _room = room;
  57. }
  58. - (Room *)room{
  59. return _room;
  60. }
  61.  
  62. 问题:房间无法被释放了怎么办?
  63. 解决方法:
  64. 在对象被释放时,要把该对象的所有对象类型的成员变量在dealloc当中进行释放:
  65. @implementation Gamer
  66. - (void)dealloc
  67. {
  68. [_room release];//堆中对象的计数器变量减1
  69. NSLog(@"玩家被释放");
  70. [super dealloc];
  71. }
  72. @end
  73.  
  74. 解决方案:判断新进房间与之前是否是同一个房间。
  75. - (void)setRoom:(Room *)room
  76. {
  77. if (_room != room) {
  78. // 释放旧房间
  79. [_room release];
  80. [room retain];//加1后赋值
  81. _room = room;
  82.  
  83. }
  84. }
  85.  
  86. 总的来说,有以下几点规律:
  87. 2)只要想要使用1个对象,那么就让对象的引用计数器+1。
  88. 3)当不再使用这个对象时,就让对象的引用计数器-1。
  89.  
  90. 需求:
  91. 1、让玩家换房间,进入1号房间后,再进入2号房间
  92. // 实现玩家类
  93. @implementation Gamer
  94. - (void)setRoom:(Room *)room
  95. {
  96. [_room release];//旧房间的计数器变量减1
  97. _room = [room retain];//新房间的计数器变量加1后赋值
  98. }
  99. - (Room *)room{
  100. return _room;
  101. }
  102. - (void)dealloc
  103. {
  104. [_room dealloc];
  105. NSLog(@"玩家被释放");
  106. [super dealloc];
  107. }
  108. @end
  109. int main(){
  110. // 1、创建玩家对象
  111. Gamer *game = [[Gamer alloc] init];
  112. // 2、创建房间对象
  113. Room *room = [[Room alloc] init];
  114. room.no = 1;
  115. Room *room1 = [[room alloc] init];
  116. room.no = 2;
  117. // 3、让玩家进入房间
  118. game.room = room;
  119. game.room = room1;
  120. // 4、释放房间对象
  121. [room release];
  122. // 5、释放玩家对象
  123. [game release];
  124. return 0;
  125. }
  126.  
  127. 总结:
  128. 1、set方法的内存管理
  129. - (void)setRoom:(Room *)room
  130. {
  131. if(_room != room){
  132. [_room release];
  133. _room = [room retain];
  134. }
  135. }
  136. 2、dealloc方法内存管理
  137. - (void)dealloc
  138. {
  139. // 当玩家不在了,代表不用房间了
  140. // 对房间进行一次release
  141. [_room release];
  142. // 重写dealloc方法,必须在最后调用父类的dealloc方法
  143. [super dealloc];
  144. }

House.h

  1. #import <Foundation/Foundation.h>
  2.  
  3. @interface House : NSObject
  4. @property int no;
  5. @end

Huose.m

  1. #import "House.h"
  2.  
  3. @implementation House
  4. - (void)dealloc
  5. {
  6. NSLog(@"%d房间被释放了",_no);
  7. [super dealloc];
  8. }
  9. @end

main.m

  1. /**
  2. 知识回顾:
  3. 什么是内存管理:
  4. 管理堆区的内存的分配和释放.
  5. 分配内存:new alloc copy
  6. 释放内存:release
  7.  
  8. 操作内存的方式:
  9. 1)retainCount:获取对象的计数器的值
  10. 2)retain:堆内存中对象的计数器变量 +1
  11. 3)release:堆内存中对象的计数器变量 -1
  12.  
  13. 僵尸对象:已经被释放的对象
  14. 野指针:指向僵尸对象的指针
  15. 空指针:nil,给空指针发送消息不会报错.
  16.  
  17. 单个对象的内存管理
  18. Person *p = [[Person alloc] init]; // 计数器 1
  19. [p retain]; // 计数器 2
  20. [p retain]; // 3
  21. //想让p对象释放,怎么办?
  22. // 再做3次release
  23. [p release];
  24. [p release];
  25. [p release];
  26.  
  27. 一个对象是否被释放,通过什么方式确定?
  28. 通过是否调用dealloc方法,在重写dealloc方法时,必须在最后的位置调用[super dealloc];
  29.  
  30. 多对象内存管理:
  31. 1.模拟1个玩家进入1个房间的过程.
  32. 分析:类:玩家,房间类,让玩家拥有一间房
  33.  
  34. 2.换房间的一个过程,玩家先进入10号房间,再进入20号房间.此时有什么问题?
  35. 解决方法:
  36. 在换房间时,需要release旧值,retain新值.
  37.  
  38. */
  39. #import <Foundation/Foundation.h>
  40. #import "Gamer.h"
  41.  
  42. int main(int argc, const char * argv[]) {
  43. @autoreleasepool {
  44. Gamer *g = [[Gamer alloc] init]; //g 1
  45.  
  46. House *h = [[House alloc] init]; //h 1
  47. //g.house = h只是表示h变量多了一个引用的指向,[[House alloc] init]对象任然只有一个引用,因为没有调用retain方法所以计数器变量不会加1.
  48. // g.house调用了g的setHouse方法所以此时[[House alloc] init]对象的引用为2
  49. g.house = h;
  50.  
  51. [h release]; // h 1
  52.  
  53. g.house = h; // 再重写进入房间
  54.  
  55. NSLog(@"%lu",h.retainCount);
  56.  
  57. }
  58. return ;
  59. }
  60. // 换房间
  61. void demo()
  62. {
  63. Gamer *game = [[Gamer alloc] init]; // game :1
  64.  
  65. House *house = [[House alloc] init]; // house :1
  66. house.no = ;
  67.  
  68. House *house2 = [[House alloc] init];
  69. house2.no = ;
  70.  
  71. House *house3 = [[House alloc] init];
  72. house3.no = ;
  73.  
  74. // 让人进入10号房
  75. game.house = house;
  76.  
  77. // 让人进入20号房间
  78. game.house = house2;
  79.  
  80. // 让人进入20号房间
  81. game.house = house3;
  82.  
  83. // 释放房间
  84. [house release];
  85. [house2 release];
  86. [house3 release];
  87. [game release];
  88.  
  89. }

oc-31-多对象的内存管理的更多相关文章

  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 第五天(内存管理)

    OC的重点: 内存管理 1 基本原理     OC的内存回收机制是和JAVA的自动回收机制是不同的,它有两种模式,或者准确的说是同 一种模式的两种不同体现,下面简单总结下. 1手动内存回收       ...

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

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

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

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

  7. C++解析(31):自定义内存管理(完)

    0.目录 1.遗失的关键字mutable 2.new / delete 3.new[] / delete[] 4.小结 5.C++语言学习总结 1.遗失的关键字mutable 笔试题: 统计对象中某个 ...

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

    直接上图啊.

  9. OC开发系列-内存管理

    概述 移动设备的内存极其有限,每个app所有占用的内存是有限的.当app所占用的内存比较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间. 任何集成了NSObject的对象都需要手动进行 ...

  10. OC内存管理(MRC)

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

随机推荐

  1. 反汇编一个简单的C程序

    一.实验截图 二.汇编代码分析: cpu首先执行main函数里的pushl %ebp和movl %esp %ebp.如下图: esp减去4就是向上移动4位到1,如下图: 把1赋值给esp,如下图: c ...

  2. 机器学习(1)_R与神经网络之Neuralnet包

    本篇博客将会介绍R中的一个神经网络算法包:Neuralnet,通过模拟一组数据,展现其在R中是如何使用,以及如何训练和预测.在介绍Neuranet之前,我们先简单介绍一下神经网络算法. 人工神经网络( ...

  3. 门户级UGC系统的技术进化路线——新浪新闻评论系统的架构演进和经验总结(转)

    add by zhj:先收藏了 摘要:评论系统是所有门户网站的核心标准服务组件之一.本文作者曾负责新浪网评论系统多年,这套系统不仅服务于门户新闻业务,还包括调查.投票等产品,经历了从单机到多机再到集群 ...

  4. webrtc--AudioProcessing的使用

    1.AudioProcessing的实例化和配置: AudioProcessing* apm = AudioProcessing::Create(0); apm->level_estimator ...

  5. 【原创】用Pwnage + Redsnow 制作完美越狱固件

    原帖我发表在威锋论坛 现在貌似IOS 7.X系 大行其道,就算不是IOS7.X ,很多人也装着IOS 6.X系. 进入正文前首先介绍一下自己目前的"环境" 设备:iphone4 G ...

  6. UIView UITableView 背景图片添加

    这几天,经常用到为某个视图设置背景图片,而API中UIView没有设置背景图片的方法,搜集归纳如下: 第一种方法: 利用的UIView的设置背景颜色方法,用图片做图案颜色,然后传给背景颜色. UICo ...

  7. Objc基础学习记录2

    1.[类 方法名]; //类方法,-静态成员函数, + (void)fun; 2.[对象名 方法名]; //实例方法, -非静态成员函数, - (void) fun; 3.带有冒号必须要有参数; 4. ...

  8. mahout算法源码分析之Itembased Collaborative Filtering(四)共生矩阵乘法

    Mahout版本:0.7,hadoop版本:1.0.4,jdk:1.7.0_25 64bit. 经过了SimilarityJob的计算共生矩阵后,就可以开始下面一个过程了,这个过程主要是共生矩阵的乘法 ...

  9. asp获取勾选checkbox的值

    Dim str_select  str_select = CStr(request.Form("c_name")) c_name是checkbox的name

  10. 关于WebPlayer Sandbox的小节

    不可以像其他build target一样读写I/O 不可以call一些private或者internal methord 只要在一个top level的domain下可以不需要xml dmain po ...