一、
1.内存分区图:高地址 栈 区:局部变量 代码块结束时,系统自动释放,不需要进行管理
堆 区:创建的对象 而在堆区中创建的对象不会自动释放,需要我们进行管理
BSS段:未初始化的全局变量和静态变量 ]
数据段:初始化的全局变量和静态变量 ]此三项程序启动时,自动加载
低地址 代码段:代码 ]
2.OC的内存管理对象是任何继承自NSObject的类的对象,对基本数据类型无效。
3.OC的内存管理分类:MRC(MannulReference Counting) 手动管理
ARC(AutomaticReference Counting) 自动管理
二、MRC和ARC下单个对象的内存管理问题
1.首先我们来看MRC下单个对象的内存管理:野指针和僵尸对象
建一个类,并把所在的target设置为MRC
#import <Foundation/Foundation.h>
@interface Person:NSObject
-(void)run;//声明run方法
@end
@implementation Person
-(void)dealloc{//重写dealloc方法
NSLog(@"Life is over");
[super dealloc];//调用dealloc方法
}
-(void)run{
NSLog(@"Person is running");//实现run方法
}
@end
int main()
{
@autoreleasepool {
Person *person=[[Person alloc]init];//创建一个对象person,此时其引用计数器为1
[person release];
[person run];
按照内存管理的原则之一,谁创建谁release,把person释放,此时运用计数器为0。此时调用run方法打印出了结果,按理说会报错,因为对象已经不存在了。但没有报错,打开僵尸检测,确确实实报错了。此时,person就是一个野指针,指向了一块对象已经被释放的内存空间及僵尸对象。僵尸对象的管理,是在对象release以后,把指针赋值为nil
}
return 0;
}
2.ARC下单个对象的内存管理问题:主要分析的是对象在强指针和弱指针引用时的释放情况
建一个学生类,此时所创建的target默认的便是ARC
#import <Foundation/Foundation.h>
@interface Student:NSObject
@property(nonatomic,copy)NSString *name;
-(instancetype)initWithName:(NSString *)name;
@end
@implementation Student
-(instancetype)initWithName:(NSString *)name{
if (self=[super init]) {
self.name=name;
}
return self;
}
-(void)dealloc{
NSLog(@"%@ is over",_name);//能重写dealloc,但不能调用[super dealloc]
}
@end
int main(){
@autoreleasepool {
__strong Student *student=[[Student alloc]initWithName:@"1"];
//此时,不能写retain、release和autorelease,对象也会释放。而判断对象是否释放的唯一标准就是有无强指针指向
//什么都不加时,默认的是强指针指向 例: Student *student=[Student new];
// 运行结果
// 2016-01-24 15:08:57.077 博客[628:15156] 1 free
// 2016-01-24 15:08:57.078 博客[628:15156] 2 is over
// 2016-01-24 15:08:57.078 博客[628:15156] (null) free
// 2016-01-24 15:08:57.079 博客[628:15156] 1 is over
// Program ended with exit code: 0
//运行可以看出2早于1先被释放,因为被强指针指向的对象会在@autorelease所在的花括号结束时释放,而被弱指针指向的对象在声明完成后立即释放
NSLog(@"%@ free",student.name);
__weak Student *student1=[[Student alloc]initWithName:@"2"];//声明完成后立即释放
NSLog(@"%@ free",student1.name);
}
return 0;
}