首先了解一下内存的基本概念

内存分为五大区:从上到下依次为:

栈区,堆区,BSS段,数据区,代码区

栈区:局部变量  特点:存放的地址从高到低分配,函数结束的时候或者代码块结束的时候自动回收

堆区:程序运行过程中动态分配的存储空间  存放的地址从低到高

BSS段:没有初始化的全局变量和静态变量

数据区:已经初始化的全局变量和静态变量以及字符串常量

代码区:程序编译后的代码内容

移动设备的内存有限,所以每一个app的内存是有限制的,当一个app内存使用超过20M,系统就会想app发出memory warning,然后app收到消息后会回收一些不再继续使用的内存空间,比如一些不再使用的对象和变量等

为什么要管理内存:程序启动的时候会首先加载代码区,数据区,bss段的内容,这三块地方系统启动后自动加载运行的,所以内存不需要我们管理,栈区的局部变量在函数结束和代码块结束会自动回收,也不需要我们手动管理,所以我们管理的是堆区中的 (nsobject <-实例<- 对象)内存

管理范围:管理任何继承于NSObject的对象,对其它基本数据类型无效

内存泄露:代码块结束时所有局部变量会被回收,指向对象的指针也会被回收,此时对象已经没有指针指向,但是依然存在于内存中,造成内存泄露

一.内存管理的方式

1.MRC

手动引入计数

2.ARC

自动引入计数

二.MRC模式下的内存管理

首先我们创建一个Dog类

Dog.h:

#import <Foundation/Foundation.h>

@interface Dog : NSObject
{
    int _ID;
}
@property (assign) int ID;
@end

Dog.m

#import "Dog.h"

@implementation Dog
@synthesize ID = _ID;

-(void)dealloc
{
    NSLog(@"dog is death");
    [super dealloc];
}

@end

1.引入计数器的应用

        Dog *dog = [[Dog alloc]init];  //开辟一个内存空间,指针dog指向该空间
        NSLog(@"%zd",dog.retainCount);  //值为1
        
        Dog *dog1 = dog;
        NSLog(@"%zd",dog.retainCount);  //值为1,说明在mrc模式下直接赋值dog是无效的
        
        Dog *dog2 = [dog retain];
        NSLog(@"%zd",dog.retainCount);  //值为2
        
        Dog *dog3 = [dog retain];
        NSLog(@"%zd",dog.retainCount);  //值为3
        
        [dog1 release];
        dog1 = nil;  //防止指针错位
        NSLog(@"%zd",dog.retainCount);  //值为2 因为指向内存空间的少了一个dog
        
        [dog2 release];
        dog2 = nil;
        NSLog(@"%zd",dog.retainCount);  //值为1
        
        [dog release];
        dog = nil;
        NSLog(@"%zd",dog.retainCount);  //值为0

2.内存管理分析

当引入计数器为0时,系统会自动触发析构函数来回收内存  

3.内存管理-->黄金法则

对一个OC对象进行alloc,retain,copy,mutableCopy的时候需要对该对象进行release或者autoRelease操作

 

posted on 2016-06-25 22:27  chengkaihua  阅读(229)  评论(0编辑  收藏  举报