iOS中内存管理方案

本文探讨了iOS系统中的三种内存管理方案:TaggedPointer适用于小对象,如NSNumber和NSString;NONPOINTER_ISA在64位架构下用于内存管理;散列表用于复杂数据结构的引用计数和弱引用管理。详细分析了TaggedPointer、NONPOINTER_ISA的结构和特点,并解释了alloc和dealloc过程中涉及的内存管理细节。
摘要由CSDN通过智能技术生成

系统提供的有不同的内存管理方案,大致有如下三种:

  • TaggedPointer (对于一些小对象,比如说NSNumber,NSString等采用此种方案)
  • NONPOINTER_ISA (64位架构下iOS应用程序)
  • 散列表 (散列表为复杂的数据结构,包含了引用计数表和弱引用表)

TaggedPointer

以下2段代码能发生什么事?有什么区别?

- (void)setName:(NSString *)name
{
    if (_name != name) {
        [_name release];
        _name = [name retain];
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    for (int i = 0; i < 1000; i++) {
        dispatch_async(queue, ^{
            // 加锁
            self.name = [NSString stringWithFormat:@"abcdefghijk"];
            // 解锁
        });
    }
    
//    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//
//    for (int i = 0; i < 1000; i++) {
//        dispatch_async(queue, ^{
//            self.name = [NSString stringWithFormat:@"abc"];
//        });
//    }
    
//    NSString *str1 = [NSString stringWithFormat:@"abcdefghijk"];

//    NSLog(@"%p", str1);
}

当赋值为abc的时候,会当成是一个TaggedPointer,直接修改成员变量,故不会报错,当赋值为abc的时候,会当成是一个NONPOINTER_ISA,多条线程同时操作一个属性,在nonatomic下面会有多线程的问题,如果要解决这个问题,可以把属性改成atomic。(就是判断isTaggedPointer,在mac平台,指针的最低有效位是1,就是TaggedPointer;在ios平台,指针的最高有效位是1,就是TaggedPointer)

NONPOINTER_ISA

indexed:0:这里存的是当前对象的类对象地址;1:除地址外还有内存管理方面数据

has_assoc:当前对象是否有关联对象

has_cxx_dtor:当前对象是否有使用到C++方面的内容

shiftcls:当前对象类对象的指针地址

wealy_referenced:是否有相应的弱引用指针

deallocting:是否正在进行dealloc操作

has_sidetable_rc:是否内存管理数据过大,过大或用sidetable储存

extra_rc:储存内存管理相关

散列表方式

alloc

 用alloc的时候并没有引用计数+1,通过一系列调用,最终调用c函数的calloc;


 

dealloc:

可以看到执行过程比较简单,_objc_rootDealloc -> rootDealloc -> objc_object::rootDealloc,

在objc_object::rootDealloc中判断对象的几个条件:

  1. isa.nonpointer,32位系统和64位系统isa的结构不同,为0表示isa直接指向对象的class,为1表示isa不是直接指向class
  2. 是否有注册weak引用表
  3. 是否有association关联属性
  4. 是否有c++析构
  5. 是否有引用计数表

在object_dispose中调用objc_destructInstance主要做了以下操作:

  1. object_cxxDestruct,这里主要是用于释放对象的实例变量
  2. _object_remove_assocations,移除掉所有关联属性,即通过objc_setAssociatedObject添加的关联属性
  3. clearDeallocating,先清空weak变量表且将所有weak引用指向nil,然后清空引用计数表。

最后通过free函数清除对象内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值