内存管理知识点总结

一、内存区域分类:

1、堆区:需要的时候系统会为你分配内存,但是系统不会自动回收,需要程序员手动释放内存

2、栈区:需要的时候系统会为你分配内存,不需要的时候系统自动回收该内存

3、常量区:存储常量,数据不能修改

4、全局,静态区:存储全局变量和静态变量

5、自由存储区

二、注意:

1、内存管理只针对继承NSObject的对象,对其他基本数据类型无效(int double NSRange等)

2、mac OS 有垃圾回收机制,但iOS没有,其内存管理需要开发者处理

3、内存管理的目的:保证每个对象在使用的时候存在内存中,不用的对象在最后从内存中清除

4、悬垂指针:如果在最后打印对象的retainCount应该为0,但因为悬垂指针结果会是1,所以retainCount仅仅作为参考,不能进行逻辑判断,可以在dealloc函数中添加一句输出语句来验证是否对象已经不存在

5、常量不需要内存管理,如果打印其retainCount为正无穷

6、要获取一个对象的持有权,引用计数必须加1,所以在初始化时要注意,不能用常规的,在MRC状态下,多个对象内存管理需要如下操作:

 1 - (void)setBook:(Book *)book {
 2
 3     // 比较两个是否是同一个对象,所以用 !=
 4     if (_book != book) {  // 判断旧的和新的是否是同一个,如果是同一个,不需要释放,不操作
 5
 6        [_book release];   // 当重新赋值的时候,走set方法,把之前的联系解除(释放旧的)
 7
 8        _book = [book retain];    // 保证用户持有该对象 ---- 引用计数必须加1(持有新的)
 9
10     }
11 }
12
13
14 // ----------------- 自定义初始化的方法 (不需要release,在dealloc里面释放) --------------
15 - (instancetype)initWithBook:(Book *)book andName:(NSString *)name {
16     self = [super init];
17     if (self) {
18         _book = [book retain]; // 保证持有
19
20         _name = [name retain];;
21     }
22     return self;
23 }
24
25
26 #pragma mark - 便利构造
27 + (Person *)personWithBook:(Book *)book andName:(NSString *)name {
28     Person *per = [[Person alloc]initWithBook:book andName:name];
29
30     return [per autorelease]; // 不能直接用release,因为那样无法返回
31 }

7、在类的实现文件中,必须包含dealloc方法:

// 当retainCount为0时,自动走该方法,无需自己调用   可以根据程序是否走该方法判断对象是否释放
- (void)dealloc {

    NSLog(@"person dealloc");

    [_book release];   // 在哪里持有,哪里释放,所以当person没有的时候,释放其持有
    // 上面也可以写成_book = nil; 效果相同

    [_name release];    // 属性 必须在dealloc中释放å

    [super dealloc];
}

8、集合中的内存管理

某个对象加入到数组中,其retainCount + 1,不影响数组的retainCount

数组的retainCount改变,不影响数组里面的元素的retainCount

数组对象被销毁时,里面的对象元素,retainCount - 1 注意不是清零      示例代码如下:

Person *per = [[Person alloc]init];
        NSArray *array = [[NSArray alloc]initWithObjects:@"1", @"2", per, nil];

        NSLog(@"per = %lu, arr = %lu", per.retainCount, array.retainCount);

        [array retain];
        NSLog(@"per = %lu, arr = %lu", per.retainCount, array.retainCount);

        [array release];
        [array release];// 数组销毁的时候会使per的retainCount -1 ,所以下面只需要一次release
        [per release];

三、自动释放池

如果对象是在自动释放池中,则不需要release,因为在程序结束的时候,自动释放池会自己清除其里面的内容

 1 //        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
 2 //        [pool release];     被封装
 3
 4         // 当pool release的时候,所有加autorelease的retainCount - 1
 5
 6         Person *per = [[Person alloc]init];
 7         [per retain];
 8         [per autorelease];
 9         [per autorelease];
10
11         NSLog(@"per = %lu", per.retainCount);
12
13         NSArray *array = [[[NSArray alloc]initWithObjects:@"1", nil]autorelease];
14         // 等价于上面alloc + autorelease, 系统的便利构造方法不需要内存管理
15
16         NSArray *array1 = [NSArray arrayWithObjects:@"2", nil];

四、循环引用:让其中一个引用变为弱引用(assign),在相互导入的时候,一个用@class,并在.m文件中用#import导入 示例如下:

 1 #import <Foundation/Foundation.h>
 2
 3 @class Person;    // 互相引用的时候,防止循环引用  不能再.m文件中访问其属性和方法,所以要在.m 中import Person.h
 4
 5 @interface Book : NSObject
 6
 7 @property (nonatomic,assign) Person *per;   // 不会让引用计数加1,弱引用,打破平衡,让其中一个先减为0,才会进入dealloc
 8
 9
10 @end

四、其他错误总结:

ARC:

1. retain(copy)  -- strong

2. weak  修饰不需要持有的对象类型

MRC:

不需要持有对象:assign

需要持有对象:retain copy

 1         NSString *str = @"cassie";
 2
 3         NSLog(@"常量:%lu", str.retainCount);
 4
 5         NSString *str1 = [[NSString alloc]initWithFormat:@"你好"];
 6
 7         [str1 release];             //   中文 -- 存在堆区,需要release
 8
 9         NSLog(@"中文str:%lu", str1.retainCount);
10
11 //      所以在用NSString类型的对象时,用release,防止内存泄露

谁持有谁释放(遵循原则)  错误示例及解释如下:

NSArray *array = @[@"1"]; 相当于遍历构造 不需要释放

1、混乱释放

Person * person = [[Person alloc] init];

Person * person1 = person;  person1 只是一个指针

[person1 release];// 不遵守内存管理原则,不持有person1,应该释放person

2、内存泄露

Person * person1 = [[Person alloc] init];

Person * person2 = [[Person alloc] init];

person2 = person1;//指针指向发生改变,person2原有内存 泄露, 解决方案 autorelease

3、过度释放

Person * person = [Person personWithName:@"tom" age:12];

[person release];//便利构造器初始化的对象,过度释放了,不需要release

4、nil对象的引用计数为0

Person * person = nil;

NSLog(@"%lu", [person retainCount]);

5、常量对象的引用计数为无穷

NSString * name = @"name";

NSLog(@"%lu", [name retainCount]);

常量型(英文 -- 在常量区)的字符串无需内存管理   写release没有影响

时间: 2024-11-22 22:56:49

内存管理知识点总结的相关文章

MMU内存管理单元相关知识点总结

1.MMU是Memory Management Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器.物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权,多用户多进程操作系统. 2.虚拟内存由来:许多年以前,当人们还在使用DOS或是更古老的操作系统的时候,计算机的内存还非常小,一般都是以K为单位进行计算,相应的,当时的程序规模也不大,所以内存容量虽然小,但还是可以容纳当时的程序.但随着图形界面的兴起还有用户需求的不断增大,应用程序

raywenderlich写的关于内存管理,第一篇,再说一次基础知识点

原文链接地址:http://www.raywenderlich.com/2657/memory-management-in-objective-c-tutorial 著作权声明:本文由http://www.cnblogs.com/andyque翻译,欢迎转载分享.请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢! 教程截图: 当我检查其他开发人员的代码时,似乎最常见的错误总是围绕在以Object-C中的内存管理为中心.如果您使用的语言是java或C#,它们会自动为您处理内存管理,但这也会使你

Objective-C(十六、内存管理,自动释放池,ARC,强指针,弱指针,方法族)——iOS开发基础

结合之前的学习笔记以及参考<Objective-C编程全解(第三版)>,对Objective-C知识点进行梳理总结.知识点一直在变,只是作为参考,以苹果官方文档为准~ 十六.内存管理相关知识(二) 1.autorelease,自动释放机制 - (instancetype)autorelease; (1)自动释放池的创建 iOS5.0之前 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; //进行一系列操作 //此处不可以使用

RTX——第18章 内存管理

内存管理介绍在 ANSI C 中,可以用 malloc()和 free()2 个函数动态的分配内存和释放内存,但是,在嵌入式实时操作系统中,调用 malloc()和 free()却是危险的,因为多次调用这两个函数会把原来很大的一块连续内场区域逐渐地分割成许多非常小而且彼此又不相邻的内存块,也就是内存碎片.由于这些内存碎片的大量存在,使得程序到后来连一段非常小的连续内存也分配不到.另外,由于内存管理算法上的原因,malloc()和 free()函数的执行时间是不确定的.在 RTX 中,操作系统把连

IOS阶段学习第21天笔记(ARC内存管理-Copy-代理)

IOS学习(OC语言)知识点整理 一.OC 中的ARC内存管理 1)ARC中释放对象的内存原则:看这个对象有没有强引用指向它 2)strong:强引用,默认情况下的引用都是强引用 3) weak:弱引用__weak 4)ARC环境下:与内存相关的代码都不能使用了,如果要在ARC环境下使用MRC内存管理代码 如: [super    delloc]  选中项目找到 Build Phases 菜单下的  Compile Sources 项 选中要转换的.m文件, 双击写入此行代码:-fno-objc

objective-c(内存管理)

本文主要记录objective-c 内存管理的知识点: 1.objective-c的对象都是分配内存在堆上,与C的mallock和C++的new类似,只有int等系统变量分配内存在栈上: 2.objective-c没有java这般复杂的垃圾回收机制,它用的是引用计数,可以理解为创建该对象后,指向该对象首地址的指针是否在其他地方被引用,若增加引用则引用数加一,反之减一,当引用数为零时系统清除该变量.内部应该是堆上分配的地址重新设置为有效,也就是说可以再次分配给其他对象,存储该对象首地址的指针清除,

block没那么难(三):block和对象的内存管理

本系列博文总结自<Pro Multithreading and Memory Management for iOS and OS X with ARC> 在上一篇文章中,我们讲了很多关于 block 和基础变量的内存管理,接着我们聊聊 block 和对象的内存管理,如 block 经常会碰到的循环引用问题等等. 获取对象 照例先来段代码轻松下,瞧瞧 block 是怎么获取外部对象的 /********************** capturing objects **************

C++内存管理学习笔记(4)

/****************************************************************/ /*            学习是合作和分享式的! /* Author:Atlas                    Email:[email protected] /*  转载请注明本文出处: *   http://blog.csdn.net/wdzxl198/article/details/9094793 /************************

Oracle 11G R2的内存管理

基本知识点 基本的内存结构:SGA+PGA+UGA+Software code area(软件代码区) 了解SGA内存的组件与一些常用的功能 了解oracle 11G地自动内存管理功能 具体介绍 oracle数据库实例是由一些列的系统全局区域与后台进程组成. 一个客户端访问数据库的方式是客户端进程---->Program global are----->Database buffer cache,同时在Redo log buffer重写一份 oracle 内存管理的方式:自动内存管理与手动内存