iOS 内存管理内存管理

iOS MRC/ARC内存管理基础篇

2017-06-26  本文已影响71人  shannoon

1. 引用计数(Reference Count)

2. OC内存管理三个进程(针对Cocoa类,CFType不包含在内)

MRC中内存管理规则:

autorelease和Autoreleasepool:

Autoreleasepool理解
// {}中的代码
void *context = objc_autoreleasePoolPush();
objc_autoreleasePoolPop(context);

magic 用来校验 AutoreleasePoolPage 的结构是否完整;
next 指向最新添加的 autoreleased 对象的下一个位置,初始化时指向 begin() ;
thread 指向当前线程,所以AutoreleasePool是按线程一一对应的
parent 指向父结点,第一个结点的 parent 值为 nil ;
child 指向子结点,最后一个结点的 child 值为 nil ;
depth 代表深度,从 0 开始,往后递增 1;
hiwat 代表 high water mark 。
另外,当 next == begin() 时,表示 AutoreleasePoolPage 为空;当 next == end() 时,表示 AutoreleasePoolPage 已满。

ARC下的内存管理:

3. CoreFoundation的内存管理

Core Foundation 对象必须使用CFRetainCFRelease来进行内存管理。

实际上 Core Foundation 对象使用的 CFRetain 和 CFRelease 方法,可以认为与 Objective-C 对象的 retain 和 release 方法等价,所以我们可以以 MRC 的方式进行类似管理,有一个小习惯注意养成CFRelease (cfobj)之前,判断cfobj是否为nil,不为nil时再调用release

当使用Objective-C 和 Core Foundation 对象相互转换的时候,怎么处理?

必须让编译器知道,到底由谁来负责释放对象,是否交给ARC处理。只有正确的处理,才能避免内存泄漏和double free导致程序崩溃。

__bridge:只做类型转换,不
修改相关对象的引用计数,不修改所有权. 例如:原来对象是 Core Foundation ,那么对象在不用时,需要调用 CFRelease 方法。

__bridge_retained:类型转换后,将相关对象的引用计数加1

__bridge_transfer:类型转换后,将相关对象的引用计数交给对方权限管理

我们根据具体的业务逻辑,合理使用上面的三种转换关键字,就可以解决 Core Foundation 对象与 Objective-C 对象相对转换的问题了。

4.其他小知识点:

5.MRC下写set,init等方法:


- (instancetype)initWithName:(NSString *)name dog:(Dog *)dog
{
    if (self = [super init]) {
        // init方法中不需要判断_name和name是否不同,因为只会在初始化的时候调用一次
        _name = [name copy];
        _dog = [dog retain];
    }
    return self;
}

- (void)setDog:(Dog *)dog
{
    if (_dog != dog) {
        // 因为用不到旧的dog了,所以对旧的dog做一次release,
        [_dog release];
        
        // 要强引用新的dog,对新的dog做一次retain,
        _dog = [dog retain];
    }
}

- (void)setAge:(NSInteger)age
{
    _age = age; // 基本数据类型,不需要自己管理内存
}

- (NSString *)name
{
    return _name;
}

// MRC中一定要在delloc中对对象做一次release,然后最后调用super dealloc;ARC中不需要,也不能调用super dealloc
- (void)dealloc
{
    [_dog release];
    [_name release];
    [super dealloc];

}

上一篇下一篇

猜你喜欢

热点阅读