iOS开发知识

《iOS高级编程》中的内存管理基础【MRC】

2019-07-13  本文已影响0人  太阳骑士索拉尔

关于我的仓库

前言

准备工作

内存管理(引用计数)的思考(p.2 ~ p.13)

记住一张表格

对象 方法 引用计数
生成对象并自己持有 alloc/copy 变成 1
持有对象 retain ++
释放对象 release --
废弃对象 dealloc
生成但不持有对象 array -1

内存管理四大原则

  1. 自己生成的对象,自己持有
  2. 非自己生成的对象,自己也能持有
  3. 不再需要自己持有的对象时释放
  4. 非自己持有的对象无法释放

注意点

  1. 我们不要纠结于引用计数的事,引用计数本质上只是一个帮助我们观察状态的工具,合理的思考方式就是按照上面四个原则去思考
  2. 持有到底是什么意思?持有的本质其实就是强引用
NSObject *obj1 = [[NSObject alloc] init];
//这句话里面我们在内存中分配了一块空间,存放一个NSObject对象,而我们的obj1是一个指针,指向该对象
//同时,obj1也强引用即持有了该对象,会使该对象的引用计数+1
//强引用即__strong,在OC中,不佳特别的修饰符会默认为强引用

疑点

  1. 这里按照强应用即持有的观点,obj1持有了该对象,这和书上的是对象的使用环境(编程人员自身)持有对象这一观点不符
  2. 但是如果按照书上的理解,实在很难想象为什么可以对象被多个持有

内存管理四兄弟【alloc】【retain】【release】【dealloc】(p.13 ~ p.20)

说明

alloc

计数

        NSObject *obj = [[NSObject alloc] init];
   [Print printRetainCount:obj];

GNU实现

//p.15      
struct obj_layout {
    NSUInteger retained;    //引用计数
};
 
+ (id)alloc
{
    int size = sizeof(struct obj_layout) + 对象大小;    //size大小就是对象的是实际大小加上一个结构体
    struct obj_layout *p = (struct obj_layout *)calloc(1, size);
    return (id)(p + 1)  //这里应该是返回该对象的内存地址,它返回了p+1,也就是说返回了掠过引用计数结构体的内存地址
        //也就是说引用计数存在了对象的头地址里
}

retainCount

//p.15
- (NSUInteger) retainCount
{
    return NSExtraRefCount(self) + 1;
}
 
inline NSUInteger
NSExtraRefCount(id anObject)
{
    return ((obj_layout)anObject)[-1].retained; //这个[-1]实在是有点迷人,我的理解是我们这里的anObject是对象的内存地址,而上面我们看到了刨掉引用计数才是我们的内存地址,对于对象的地址是[0],[-1]是它的前一个,也就是引用计数了
}

retain

release&&dealloc

Apple实现

引用计数&&哈希表

autorelease(p.20 ~ p.28)

arrayWithCapacity

 NSMutableArray *orderIds = [NSMutableArray arrayWithCapacity:self.dataArray.count]
 初始化可变数组对象的长度,如果后面代码继续添加数组超过长度以后长度会自动扩充.
初始化方法 capacity后的NSUInteger代表了开辟内存的一个单位初始在内存中开辟5个内存,如果之后数组元素多余5个,则会再开辟新的5*2个新的内存,[考虑到数组的连续内存的特性]单位是以5,把之前的5个元素的内容拷贝到新的十个新的内存里面,把第六个也放进去,然后释放初始状态创建的内存5个最后得到了一块够用的连续的内存5*2
   
 NSMutableArray *array = [NSMutableArray alloc] init];//这并不是一个好方法

 NSMutableArray *array = [NSMutableArray arrayWithCapacity:10]; //创建一个可变的数组长度为10

区别:

1. arrayWithCapacity是类autorelease的.

2. [NSMutableArray alloc]initWithCapacity需要自己release.

苹果实现

SEL&&IMP

push&&pop

困惑

  [obj alloc]
  [obj release]
上一篇 下一篇

猜你喜欢

热点阅读