黑马程序员----Objective-C学习笔记之内存管理

------Java培训、Android培训、iOS培训、.Net培训--------

一、内存管理的基本概念及范围

1、管理范围:

1)管理任何继承NSObject的对象,对其他基本数据类型是无效的。

因为对象和基本数据类型存储的区域是不一样的。对象存储在需要内存管理的堆区,而基本数据类型存放在栈区。

2)对象类型是程序在运行过程中动态分配的,存储在堆区。

内存管理主要是【对堆区中的对象】的内存管理


二、内存管理的原理和分类

1、对象的所有权及引用计数

1)【所有权策略】

任何自己创建的对象都归自己所有,可以使用名字以“alloc”和“new”开头或名字中包含“copy”的方法创建对象,可以使用retain来获取一个对象的所有权

 

2)【对象的引用计数】retainCount

每个OC对象都有自己的引用计数器,标示【当前对象】当前有多少个东西在使用这个对象,当该对象被创建时,计数器值为1

3)【引用计数器作用】

是判断对象要不要回收的依据。

如果引用计数器为0,则就要回收该对象。

【例外】对象值为nil时,引用计数器为0,但不回收空间,因为根本就没分配空间

 

4、【对引用计数器的操作】

给对象发送消息,进行相应的计数器操作

【retain消息】使计数器+1,该方法返回对象本身

【release消息】使计数器-1,并不代表释放对象

【retainCount消息】获得对象当前的引用计数器值  %ld  %lu

 

5、【对象的销毁】

当一个对象的引用计数器为0时,那么它将被销毁,其占用的内存被系统回收

当对象被销毁时,系统会自动向对象发送一条【dealloc】消息,一般会重写dealloc方法,在这里释放相关的资源。一旦重写了dealloc方法就必须调用[super dealloc],并且放在代码块的最后调用,不能直接调用dealloc方法。

一旦对象被回收,那么他所占据的存储空间就不再可用,坚持使用会导致程序崩溃

 

【注意】

1)如果对象的计数器不为0,那么在整个程序运行过程中,它所占用的内存就不可能被回收(除非整个程序已经退出)

2)任何一个对象,刚生下来的时候,引用计数器都为1。当使用alloc、new或者copy创建一个对象时,对象的引用计数器默认就是1.

 

2、OC内存管理的分类

OC中提供了三种内存管理方式:

  1. Mannul Reference Counting MRC手动管理方式
  2. AutomaticReference Counting ARC自动引用计数
  3. Garbagecollection垃圾回收。但是IOS中不支持该技术

 

开发中如何使用:需要理解MRC,但是实际尽量使用ARC


三、手动内存管理入门

【首先关闭ARC】

1、手动管理内存实例

#import 

#pragma mark Person类定义部分
@interface Person : NSObject

@property NSString *name;
@property int age;
@end
#pragma mark Person类实现部分
@implementation Person
//对象的临终遗言,对象销毁时,会默认调用该方法
//【注意】该方法是系统根据引用计数器自动调用的,不需要手动调用
-(void)dealloc{
    NSLog(@"This person dead....");
    //再释放父类
    [super dealloc];
}
@end

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        //用Person类实例化一个对象
        Person *p = [Person new];//此时对象的所有者是自己
        
        //证明该对象有一个所有者
        NSInteger count = [p retainCount];
        NSLog(@"count1 = %lu",count);
        
        //引用计数器+1
        //两个指针指向一个对象,但是下面这个方法并不能是计数器+1
        Person *p2 = p;
        count = [p2 retainCount];
        NSLog(@"count2 = %lu",count);
        //只有通过retain方法可以使计数器+1
        Person *p3 = [p retain];
        count = [p retainCount];
        NSLog(@"count3 = %lu",count);
        
        //想要回收对象,则要想办法是retainCount从2变成0
        [p release];
        [p3 release];
        //想要证明person对象被释放了,可以重写其dealloc放法
    }
    return 0;
}

打印结果:

2015-10-06 10:32:56.855 MRCDemo[925:303] count1 = 1

2015-10-06 10:32:56.857 MRCDemo[925:303] count2 = 1

2015-10-06 10:32:56.857 MRCDemo[925:303] count3 = 2

2015-10-06 10:32:56.858 MRCDemo[925:303] This persondead....


你可能感兴趣的:(Objective-C基础)