1、内存几大区域

1> 栈区:局部变量(基本数据类型、指针变量)。
2> 堆区:程序运行的过程中动态分配的存储空间(创建的对象)。
3> BSS段:没有初始化的全局变量和静态变量。
4> 数据区:已经初始化的全局变量和静态变量。(字符串常量)
5> 代码段:程序编译后的代码的内容。

2、引用计数器

1> 引用计数器:每个继承自NSObject的对象都有一个引用计数器,用来表示当前对象有几个拥有者。
2> 引用计数器的作用:用来判断对象是否应该回收。
3> 引用计数器的操作(ARC下无法使用)
 * retain  引用计数器+1
 * release  引用计数器-1 
 * retainCount 得到引用计数器的值(点击进入NSObject.h文件,有一个 - (NSUInteger)retainCount OBJC_ARC_UNAVAILABLE 的方法)
 注:任何一个OC对象,只要一被创建出来,其引用计数默认为1;一个对象的引用计数归0的时候,对象就会被销毁。

3、关于dealloc方法

1> 对象被释放时会自动调用
2> 开发中经常重写对象的dealloc方法,用于观察对象什么时候被释放或者想要在对象释放之前做些相应的操作,dealloc方法可以看做是对象的“临终遗言”。
3> 在MRC下,重写dealloc要注意必须要在其最后调用[super dealloc]。

4、僵尸对象、野指针、空指针。

1> 僵尸对象:即指已经被销毁的对象(不能再使用的对象)
2> 野指针:指向僵尸对象(不可用内存)的指针,给野指针发送消息会报“EXC_BAD_ACCESS"错误(常见错误)。
3> 空指针:没有指向存储空间的指针(nil),给空指针发送消息没有任何反应,试想一下,用nil调用方法怎么可能有反应。而解决野指针错误的方法就是将对象的指针变为空指针。
// 先开启僵尸对象检测

 NSObject *obj = [[NSObject alloc] init];
[obj release];
// 野指针错误
[obj log:@"测试"];
// 输出台打印
2016-01-21 19:35:46.367 内存管理[2688:205046] *** -[NSObject log:]: message sent to deallocated instance 0x100113c80 (向一个已经被释放的实例对象发送了消息)

5、开发中关于ARC(自动内存管理)和MRC(手动内存管理)的常用操作

1> 将工程从ARC环境改为MRC环境(现在基本上都是ARC环境,保持默认即可)
搜索框中输入“auto”
将“YES”改为“NO”,即从ARC改为MRC了,反之改为“YES“就是从MRC改为ARC
 
2> 工程总体环境是ARC的,让工程中某个类支持MRC
开发中,我们有时候可能用到一些以前的类,而有些比较老的类库又是MRC环境的,那么可以选择增加编译开关"-fno-objc-arc”(这里以GDataXMLNode类为例)
除了关于“libxml.dylib”动态库错之外,初次将GDataXMLNode导入工程的时候,会出现大约二十个错误,按照如下图操作即可
  
 
3> 检测野指针(僵尸对象)错误
   
 

6、关于nil、Nil、NULL

1> nil是一个对象值(对象为空)  将对象等于nil。可以防止调用僵尸对象报错
2> Nil是一个类对象(类对象为空)
3> NULL是一个通用指针(泛型指针)
4> [NSNull null]是一个对象,用在不能使用nil的场合。
 

7、@property参数

1> 控制set方法的内存管理
  retain : release旧值,retain新值(用于OC对象)
  assign : 直接赋值,不做任何内存管理(默认,用于非OC对象类型)
  copy   : release旧值,copy新值(一般用于NSString,保证字符串的安全性)
 
2> 控制需不需生成set方法
  readwrite :同时生成set方法和get方法(默认)
  readonly  :只会生成get方法
  
3> 多线程管理
  atomic    :性能低(默认)
  nonatomic :性能高
 
4> 控制set方法和get方法的名称
  setter : 设置set方法的名称,一定有个冒号:
  getter : 设置get方法的名称
 

8、NSString在内存管理中的问题

// 最近在网上视频上看到的一个有趣的问题,按照视频上所讲

// 字符串有一个常量池
// 如果你需要的字符串在常量池中已经存在了,不会分配内存空间
// 使用字符串的时候:采用下面1、3、5方式获取的字符串都在常量区(嗯,这三个NSString对象跟视频上讲的一样,确实在字符常量区,因为打印其引用计数是一个巨大的数,所以判断其内存不归用户管) // 注意:视频上所讲,str2和str4的应该被分配在堆区,即内存归用户管,引用计数应该为1
// 但事实上,看下面打印的str2和str4?瞬间凌乱了,Why,说好的在堆区呢? NSString *str1 = @"abc";
NSString *str2 = [NSString stringWithFormat:@"aaa"];
NSString *str3 = [NSString stringWithString:@"abc"];
NSString *str4 = [[NSString alloc] initWithFormat:@"aaa"];
NSString *str5 = [[NSString alloc] initWithString:@"abc"];
NSString *str6 = [[NSString alloc] init]; // 在栈区?为啥它的引用计数那么大?
NSLog(@"str1 = %@ , %p , %lu",str1,str1,str1.retainCount);
NSLog(@"str2 = %@ , %p , %lu",str2,str2,str2.retainCount);
NSLog(@"str3 = %@ , %p , %lu",str3,str3,str3.retainCount);
NSLog(@"str4 = %@ , %p , %lu",str4,str4,str4.retainCount);
NSLog(@"str5 = %@ , %p , %lu",str5,str5,str4.retainCount);
NSLog(@"str6 = %@ , %p , %lu",str6,str6,str5.retainCount); // 打印

  2016-01-21 21:26:36.979 NSString内存管理问题[3269:255674] str1 = abc , 0x100004230 , 18446744073709551615

  2016-01-21 21:26:36.980 NSString内存管理问题[3269:255674] str2 = aaa , 0x61616135 , 18446744073709551615

  2016-01-21 21:26:36.981 NSString内存管理问题[3269:255674] str3 = abc , 0x100004230 , 18446744073709551615

  2016-01-21 21:26:36.981 NSString内存管理问题[3269:255674] str4 = aaa , 0x61616135 , 18446744073709551615

  2016-01-21 21:26:36.981 NSString内存管理问题[3269:255674] str5 = abc , 0x100004230 , 18446744073709551615

  2016-01-21 21:26:36.981 NSString内存管理问题[3269:255674] str6 =  , 0x7fff7c51bd00 , 18446744073709551615

// 然后说在IOS项目下又不一样,我姑且又试了一试,确实是内存地址不一样了,但是引用计数是什么鬼

  2016-01-21 21:30:42.632 NSString内存管理[3289:257683] str1 = abc , 0x106f4c050 , 18446744073709551615

  2016-01-21 21:30:42.633 NSString内存管理[3289:257683] str2 = aaa , 0xa000000006161613 , 18446744073709551615

  2016-01-21 21:30:42.633 NSString内存管理[3289:257683] str3 = abc , 0x106f4c050 , 18446744073709551615

  2016-01-21 21:30:42.633 NSString内存管理[3289:257683] str4 = aaa , 0xa000000006161613 , 18446744073709551615

  2016-01-21 21:30:42.633 NSString内存管理[3289:257683] str5 = abc , 0x106f4c050 , 18446744073709551615

  2016-01-21 21:30:42.633 NSString内存管理[3289:257683] str6 =  , 0x107279380 , 18446744073709551615

  // 最后,我不死心,又试了一下

  NSArray *array1 = [[NSArray alloc] init];

  NSLog(@"array1 = %lu",array1.retainCount);

  NSMutableArray *array2 = [[NSMutableArray alloc] init];

  NSLog(@"array2 = %lu",array2.retainCount);

 // 打印 

  2016-01-21 21:48:01.828 NSString内存管理问题[3447:267148] array1 = 2  // 妈蛋  为什么是2

  2016-01-21 21:48:01.828 NSString内存管理问题[3447:267148] array2 = 1

 // 最后

  看到最后,有这么一张图

  

   总结一下吧,不要相信retainCount的值。(不要用它去做判断)

  平常都在用ARC,也没注意到有这些问题,既然看到了,就权当了解一下。

  
  
好记性不如烂笔头!多多复习基础知识,一一记录下来还是有所收获的! 
 

【IOS学习基础】内存管理的更多相关文章

  1. iOS学习之内存管理

    1.1 引用计数 Reference Count 1.2 自动引用计数,ARC(Automatic Reference Counting) 1引用计数 引用计数(Reference Count)是一个 ...

  2. 【IOS学习基础】NSObject.h学习

    一.<NSObject>协议和代理模式 1.在NSObject.h头文件中,我们可以看到 // NSObject类是默认遵守<NSObject>协议的 @interface N ...

  3. 【OC语法快览】四、基础内存管理

    Basic Memory Management                                                           基础内存管理 If you're w ...

  4. iOS夯实:内存管理

    iOS夯实:内存管理 文章转自 内存管理 最近的学习计划是将iOS的机制原理好好重新打磨学习一下,总结和加入自己的思考. 有不正确的地方,多多指正. 目录: 基本信息 旧时代的细节 新时代 基本信息 ...

  5. IOS开发的内存管理

    关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...

  6. IOS开发小记-内存管理

    关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...

  7. java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...

  8. java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)

    概述 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又 ...

  9. [转载]对iOS开发中内存管理的一点总结与理解

    对iOS开发中内存管理的一点总结与理解   做iOS开发也已经有两年的时间,觉得有必要沉下心去整理一些东西了,特别是一些基础的东西,虽然现在有ARC这种东西,但是我一直也没有去用过,个人觉得对内存操作 ...

  10. OC基础 内存管理

    OC基础  内存管理 我们所了解的c语言内存管理,如下: (1)c语言的内存分配:char *p = (char*)malloc(100*sizeof(char)); (2)c语言的内存释放:free ...

随机推荐

  1. FFMPEG中最关键的结构体之间的关系

    FFMPEG中结构体很多.最关键的结构体可以分成以下几类: a)        解协议(http,rtsp,rtmp,mms) AVIOContext,URLProtocol,URLContext主要 ...

  2. tomcat https jks 沃通免费证书安装 解决方案

    网上百度了一天什么没百度到,最后谷歌到了一篇文章启发之下解决之. 代理谷歌网站推荐一个,可以直接上谷歌: https://www.yundou.info ----------------------- ...

  3. session的存储方式和配置

    Session又称为会话状态,是Web系统中最常用的状态,用于维护和当前浏览器实例相关的一些信息.我们控制用户去权限中经常用到Session来存储用户状态,这篇文章会讲下Session的存储方式.在w ...

  4. PHP学习笔记二

    <?php //布尔类型 $a=true; //值不区分大小写 $b=false;//整型0,浮点数0.0,空字符串,不包括任何元素的数组,空对象,null都表示false $c=0; if($ ...

  5. EF Code Frist

    EF:学习资料 http://www.cnblogs.com/libingql/category/366833.html

  6. 枚举 enum

    typedef enum : NSUInteger { <#MyEnumValueA#>, <#MyEnumValueB#>, <#MyEnumValueC#>, ...

  7. C#监听文件

    //全局变量 public static FileSystemWatcher Watcher; /// <summary>        /// 设置监听配置        /// < ...

  8. Android Studio rename module Can't rename root module

    Android Studio修改工程根目录的时候会报错, rename module Can't rename root module. 主要是该工程已经打开,再命名必须要关闭改工程,就跟正在写一个t ...

  9. Wordpress 常用代码解释

    1. 最新文章 Wordpress最新文章的调用可以使用一行很简单的模板标签 wp_get_archvies来 实现. 代码如下: <?php get_archives('postbypost' ...

  10. 禁止Chrome浏览器缓存的方法

    web开发的人经常chrome和firefox作为开发调试工具,有些时候需要禁止chrome浏览器缓存,最近也用到禁止缓存,以下介绍几种禁止chrome浏览器缓存的方法作为记录. HTML: < ...