OC基础-内存管理(一)基础原理与黄金法则

一、OC内存管理的原理

1.C/C++内存管理的缺陷

实例说明:

int * p1 = malloc(100);

int * p2 = p1;

int * p3 = p1;

Free(p2);

...

Free(p2);

第一次Free(p2),释放内存,因为p1,p2,p3指向的是同一块内存空间地址,释放了p2也就是释放了地址所指向的内存空间,这样p1,p2,p3也就成了野指针。再次使用Free(p2)就会发生段错误。


2.OC对象结构

所有OC对象都有一个计数器(retainCount),保留着当前对象被引用的次数。每一个OC对象被创建后,在占用的内存空间中总有一块4字节的内存空间 (retainCount空间),用来计数当前对象被引用的次数。


3.OC内存管理

每一个OC对象都有一个retainCount计数器,表示当前对象被引用的次数,如果计数为0,才表示真正释放了这个内存。

alloc函数是创建对象时调用的,创建完计数器+1,只会使用一次。

retain函数是对一个对象的计数器+1。

release函数是对一个对象的计数器-1,减到0就会从内存中释放。


OC类实现了引用计数器,对象知道当前被引用的次数。最初对象的计数器是1.

如果需要引用对象,可以给对象发送一个retain消息,这样对象计数器就+1

如果不需要引用对象,可以给对象发送一个release消息,这样对象计数器就-1

当计数器减到0,自动调用对象的dealloc函数,对象从内存中释放。

计数器为0的对象,不能使用release和其他方法。


OC内存管理总结:

1⃣️OC的内存管理机制与.Net和Java那种全自动的垃圾回收机制是完全不同的,本质上还是C语言的手动管理方式,只不过增加了一些自动方法。

2⃣️OC的内存管理是基于引用计数的。要做的事情只是关注计数器引用的次数,而释放内存的工作实际上是由运行环境来完成的。

3⃣️在最简单的情形中,分配的(alloc)对象,保留了(retain)一次对象,那么就需要发送两次release消息,才能释放对象所占内存。


二、内存管理的黄金法则

The basic rule to apply is Everything that increse the reference counter with alloc, copy or retain is in charge of the corresponding [auto]release.

如果你对一个对象使用了alloc、[mutable]copy、retain,那么你就必须使用相应的[auto]release。


计数器+1的方法只有三种:

alloc、[mutable]copy、retain

计数器-1的方法只有一种:

[auto]release


三、retain点语法

1.属性分类

读写权限:

readwrite(缺省):可读可写,可以使用getter和setter

readonly:只读,只能使用getter


如何存储:

assign(缺省)、retain、copy


是否考虑线程:

nonatomic:不用考虑线程安全


重设getter和setter函数名:

getter=...,setter=...


2.为什么使用点语法?

OC内存管理,正常情况下需要大量的retain和release操作,点语法可以减少它们。

Person.h

#import <Foundation/Foundation.h>
#import "Dog.h"

@interface Person : NSObject
{
    Dog * _dog;
}
//-(void)setDog:(Dog *)aDog;
//-(Dog *) dog;

@property (retain)Dog * dog;
//这一行代码可以展开为上面的两个方法。

@end

Person.m

#import "Person.h"

@implementation Person

//-(void)setDog:(Dog *)aDog{
//    if(_dog != aDog){
//        [_dog release];
//        _dog = [aDog retain];
//    }
//}
//-(Dog *)dog{
//    return _dog;
//}

@synthesize dog = _dog;
//这一行代码可以展开为上面的2个方法

-(void)dealloc{
    NSLog(@"person is dealloc");
    //[_dog release];
    //_dog = nil;
    self.dog = nil;
    //[self setDog: nil];
    [super dealloc];
}
@end

@诗未冷学习博客


你可能感兴趣的:(oc,黄金法则,OC内存管理,retain和release)