一、引用计数器

1> 栈和堆

  1. ① 主要存储局部变量
    ② 内存自动回收
  2. ① 主要存储需要动态分配内存的变量
    ② 需要手动回收内存,是OC内存管理的对象

2> 简介

  1. 作用

    ① 表示对象被引用的次数
    ② 通常由alloc、new、copy与release方法引发
    ③ 动态监测引用计数器的值,当值为0时回收对象所占的内存
  2. 使用注意

    ① 引用计数器一个NSUInteger类型的变量,占用4字节内存
    ② 在对象被创建的时候引用计数器的值被初始化为1
    ③ 每个使引用计数器加1的操作,都有一个引用计数器减1的操作与之
    对应

3> 基本概念

  1. 僵尸对象

    ① 所占用的内存已经被回收的对象
    ② 僵尸对象不能再被使用
  2. 野指针

    ① 指向僵尸对象的指针
    ② OC中引用野指针会报错,错误信息:EXC_DAB_ACCESS
  3. 空指针

    ① 没有指向任何内存地址的指针
    ② 空指针的值通常为nil、NULL或0
    ③ 通常在创建指针时将其初始化,避免其指向不确定的内存
    ④ 在对象被销毁后,通常要将指向对象的指针赋值为nil,避免产生野
    指针

4> 基本方法

  1. retain

    ① 使引用计数器加1
    ② alloc、new、copy等方法会自动调用retain方法
    ③ 每个retain方法都必须对应一个release方法
    ④ 返回值为对象本身
  2. release

    ① 使引用计数器减1
    ② 没有返回值
    ③ 用空指针调用release方法不会报错
    ④ 不是经过alloc方法创建的对象,不需要执行release操作
  3. dealloc

    ① 在对象被销毁时调用
    ② 通常需要重写dealloc方法
    ③ 重写dealloc方法时,必须在最后调用父类的dealloc方法
    ④ @property不会影响dealloc方法,只会影响色图特人和getter

二、多对象内存管理

1> 基本使用

  • 当拥有某个对象时,就对该对象执行retain操作
  • 当抛弃某个对象时,就对该对象执行release操作
  • 谁执行retain操作,谁就执行release操作

2> set方法的内存管理

  1. 基本使用

    ① 当set方法的参数是OC对象时,通常要在set方法内实现内存管理
    ② 当参数与成员变量不一样时,才对成员变量执行release操作,对
    参数执行retain
  2. set方法的代码规范

    ① 基本数据类型:直接赋值
    ② OC对象类型
    1)先判断是不是新对象
    2)若是,对就对象执行一次release操作,对新对象执行一次retain
    操作
    3)否则,不执行操作
  3. dealloc方法的代码规范

    ① 对self拥有的所有对象执行一次release操作
    ② 一定要调用父类的dealloc方法,且放在最后
    ③ 在ARC环境下重写dealloc方法不能调用父类的dealloc方法

3> @property对内存的影响

  1. 基本使用

    ① 为成员变量生成setter和getter
    ② 默认生成的setter执行的是直接赋值,不涉及内从管理
    ③ 若setter的参数是OC对象,需要设置@property的参数,使其生成
    内存管理代码
  2. @property的参数

    ① 内存管理相关参数
    1)retain:release旧对象,retain新对象(适用于OC对象类型)
    2)assign:直接赋值(默认,适用于非OC对象)
    3)copy:release旧对象,copy新对象 ② 控制成员变量属性的参数
    1)readwrite:同时生成setter和getter的声明、实现
    2)readonly:只会生成getter的声明、实现 ③ 多线程管理相关参数
    1)nonatomic:生成setter方法时不加线程管理代码,性能高
    (一般用这个)
    2)atomic:生成setter方法时加上线程管理代码,性能低(默认) ④ 指定setter和getter名称的参数
    1)通过setter指定生成的set方法的名称,通过getter指定生成的
    get方法的名称
    2)不影响点语法的使用,点语法在使用时先转换为对应的set或get
    方法
    3)通常当get方法的返回值为BOOL类型数据时,对get方法使用,
    set方法几乎不用

4> 循环包含与循环引用

  1. 循环包含

    ① 但两个类的声明文件循环包含时,通常要在一个文件中用@class
    声明另一个类
    ② 使用规范
    1)在.h文件中用@class声明类
    2)在.m文件中用#import包含类的声明文件
  2. 循环引用

    ① 当两个OC类循环引用时,会产生内存管理问题
    ② 解决方法
    1)在一个类的声明中,指定@property的内存管理参数为retain
    2)在另一个类的生命中,指定@property的内存管理参数为release

三、autorelease

1> 基本使用

  1. 作用

    ① 将调用该方法的对象放进自动释放池,当池子销毁时,对池子内所有
    的对象执行一次release操作
    ② 通常在对象创建时调用,放回对象本身
  2. 自动释放池的创建方式

    ① 通过@autoreleasepool{}创建
    ② 通过NSAutoreleasePool类创建

2> 使用注意

  • 自动释放池的创建和释放遵循栈规则
  • 调用autorelease方法不会对引用计数器产生影响
  • autorelease方法延迟了对象的释放时间,占用内存较大的对象不要使用
  • 一个对象不能多次调用autorelease方法
  • 一个对象不能同时使用autorelease方法和release方法

3> 常见应用

  • 快速创建一个自动释放池内的对象

     ① 通常设计一个类方法,快速创建一个自动释放池内的对象
    ② 方法名通常以类名开头
    ③ 创建时要使用self调用alloc、init与autorelease方法,不要使用类名

四、ARC

1> 基本使用

  1. 强指针与弱指针

    ① 强指针
    1)通过__strong声明的指针
    2)所有的指针默认都是强指针
    ② 弱指针
    1)通过__weak声明的指针
    2)当弱指针指向的对象被释放,弱指针将被清空
  2. 判断准则

    只要没有强指针指向对象,对象就会被释放

2> @property的strong和weak参数

  • strong参数相当于retain参数
  • weak参数相当于assign参数

3> 循环引用的解决方法

  • 将@property一端的参数指定为strong
  • 将@property另一端的参数指定为weak

五、示例(多文件)

/*
1.创建一个Person类和一个Dog类,Person类与Dog类是相互用有关系
2.重写Person类与Dog类的dealloc方法
3.重写Person类的set方法,实现内存管理代码
4.自定义Person类构造方法,用于快速创建一个自动释放池内的Person对象
*/ /*****main.m文件******/
#import <Foundation/Foundation.h>
//包含Person类的声明文件
#import "Person.h"
//包含Dog类的声明文件
#import "Dog.h" int main()
{
//创建自动释放池
@autoreleasepool { //创建Dog对象,并加入到自动释放池中
Dog *d = [[[Dog alloc] init] autorelease];
/*通过调用类方法快速创建一个Person类型的自动释放池对象
并用Dog初始化新创建的对象的成员变量*/
Person *p = [Person personWithDog:d]; //将指针清空
p = nil; }
return 0;
} /*****Person.h文件******/
#import <Foundation/Foundation.h> //声明Dog是一个类,Dog.h文件用#import指令
@class Dog; @interface Person : NSObject
/*通过@property生成dog属性的getter和setter
并使用参数retain,Dog.h使用assign参数*/
@property (nonatomic, retain) Dog *dog; /*自定义方法,快速创建一个Person类型的自动释放池对象,
并用Dog初始化新创建的对象的成员变量*/
+ (Person *)personWithDog:(Dog *)dog;
@end /*****Person.m文件******/
#import "Person.h"
//使用@class声明的类,在实现文件中要用#import指令包含该类的头文件
#import "Dog.h" @implementation Person
+ (id)personWithDog:(Dog *)dog
{
Person *p = [[[Person alloc] init] autorelease];
//将dog赋值给新创建对象的成员变量
p.dog = dog;
return p;
} //重写dealloc方法
- (void)dealloc
{
NSLog(@"Person对象被释放");
//释放person所拥有的属性
[_dog release];
//调用父类的dealloc方法
[super dealloc];
}
@end /*****Dog.h文件******/
#import <Foundation/Foundation.h> //包含Person.h头文件,Person.h文件用@class指令
#import "Person.h" @interface Dog : NSObject
/*通过@property生成person属性的getter和setter
并使用参数retain,Person.h使用retain参数*/
@property (nonatomic, assign) Person *person;
@end /*****Dog.m文件******/
#import "Dog.h" @implementation Dog
//重写dealloc方法
- (void)dealloc
{
NSLog(@"Dog对象被释放");
//释放Dog所拥有的属性
[_person release];
//调用父类的dealloc方法
[super dealloc];
}
@end

OC语言-05-OC语言-内存管理的更多相关文章

  1. c语言基础学习08_内存管理

    =============================================================================涉及到的知识点有:一.内存管理.作用域.自动变 ...

  2. OC MRC之set方法内存管理(代码分析)

    // // main.m // 03-set方法的内存管理 // // Created by apple on 13-8-9. // Copyright (c) 2013年 itcast. All r ...

  3. OC第三天(内存管理)

    内存管理: 1.作用范围: 不论什么继承了NSObject的对象,堆基本数据类型无效如:int a ,float price;;等 2.原理: 每一个对象内部都保存了一个与之相关的整数,称为引用计数器 ...

  4. Objective-C 内存管理与高级环境编程 阅读分享

    常用的调试私有API uintptr_t objc_rootRetainCount(id obj) _objc_autoreleasePoolPrint();//查看自动释放池中的对象 LLVM cl ...

  5. cocos2d-x内存管理(见解)

    cocos2d-x 延续了cocos2d 和OC的引用计数的内存管理机制! 下面我们来看看CCDriectro类 CCPoolManager::sharedPoolManager()->push ...

  6. Cocos2d-x开发中C++内存管理

    由于开始并没有介绍C++语言,C++的内存管理当然也没进行任何的说明,为了掌握Cocos2d-x中的内存管理机制,是有必要先了解一些C++内存管理的知识.C++内存管理非常复杂,如果完全地系统地介绍可 ...

  7. GC与显式内存管理

    C++复兴的话题至今已被鼓吹两年有余,Herb Sutter和Bjarne Stroustrup等大牛们也为C++带来了大步伐的革新.然而,从这两年的效果而言,C++的复兴并没有发生.一方面随着世界经 ...

  8. 深入理解C指针之二:C内存管理

    原文:深入理解C指针之二:C内存管理 内存管理对所有程序来说都很重要.有时候内存由运行时系统隐式的管理,比如为变量自动分配内存.在这种情况下,变量分配在它所处的函数的栈帧上(每个函数都有它自己的栈帧, ...

  9. 【cocos2d-x 3.x 学习笔记】对象内存管理

    内存管理 内存管理一直是一个不易处理的问题.开发人员必须考虑分配回收的方式和时机,针对堆和栈做不同的优化处理,等等.内存管理的核心是动态分配的对象必须保证在使用完成后有效地释放内存,即管理对象的生命周 ...

  10. How Javascript works (Javascript工作原理) (三) 内存管理及如何处理 4 类常见的内存泄漏问题

    个人总结: 1.两种垃圾回收机制: 1)引用标记算法:如果检测到一个对象没有被引用了,就清除它. ***这种算法不能处理循环引用的情况*** 2)标记—清除算法:从根(全局变量)开始向后代变量检测,任 ...

随机推荐

  1. 【原创】C#搭建足球赛事资料库与预测平台(4) 比赛信息数据表设计

            本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源C#彩票数据资料库系列文章总目录:[目录]C#搭建足球赛事资料库与预测平台与彩票数据分析目录 本篇文章开始将逐步介 ...

  2. ubuntu14.04使用IceGridAdmin图形界面

    打开网页: http://www.rpmfind.net/linux/RPM/index.html输入搜索: icegrid-gui下载文件: icegrid-gui-3.5.1-2.mga4.x86 ...

  3. web.config中httpRunTime的属性

    配置httpRuntime也可以让FileUpload上传更大的文件,不过设置太大了会因用户将大量文件传递到该服务器而导致的拒绝服务攻击(属性有说明) <httpRuntime> < ...

  4. 从IE6到IE11上运行WebGL 3D遇到的各种坑

    这篇<基于HTML5的电信网管3D机房监控应用>基于WebGL技术的应用让少同学对HTML5 3D的应用产生了兴趣和信心,但有不少网友私信询问WebGL如何运行在老的IE678910浏览器 ...

  5. 前端翻译:Promises/A+规范

    原文地址:https://promisesaplus.com/ 本篇为原文翻译+个人理解,若有谬误请各位指正,谢谢. 尊重原创,转载请注明来自:http://www.cnblogs.com/fsjoh ...

  6. .Net魔法堂:史上最全的ActiveX开发教程——开发篇

    一.前言 在设计某移动内部自动化运维平台时,经综合考虑终端机性能和功能需求等因素后,决定采用B/S模式,并且浏览器通过ActiveX组件实现与服务器Agent作P2P的通讯.好处,整个平台以网页形式存 ...

  7. FXForms,自动生成iOS表单

    1.简介 FXForms是一个简单的表单提交框架,他的作者是鼎鼎大名的 Nick Lockwood,你也许听说过他的其他的一些框架,比如 iCarousel. 为什么使用FxForms? 表单处理简单 ...

  8. Java多线程学习笔记——信号量的使用

    Java中在控制多线程访问资源的时候使用了信号量可以控制多个线程同时访问一个资源. 有两个构造方法: public Semaphore(int permits) public Semaphore(in ...

  9. [Architect] Abp 框架原理解析(3) DynamicFilters

    本节目录 介绍 定义Filter 设置Filter 这是Abp中多租户.软删除.激活\禁用等如此方便的原因 Install-Package EntityFramework.DynamicFilters ...

  10. [Solution] 一步一步WCF(1) 快速入门

    Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台.整合了原有的windows通讯的 .n ...