OC 内存管理 ARC 分析和注意的地方

58 篇文章 2 订阅
46 篇文章 0 订阅

什么是内存管理?

程序在运行的过程中通常通过以下行为,来增加程序的内存占用:

1.创建一个OC对象

2.定义一个变量

3.调用一个函数或者方法

而一个设备的内存是有限的,每个软件所能占用的内存也是有限的

当程序苏占用的内存见多时,系统就会发出内存警告,这时就得回收一些不需要再使用的内存空间。比如回收一些不需要使用的对象,变量等

如果程序占用内存过大,系统可能会强制关闭程序,造成程序崩溃、闪退现象,影响用户体验

所以,我们需要对内存进行合理的分配内存、清除内存,回收那些不需要再使用的对象,从而保证程序的稳定性。

哪些对象才需要我们进行内存管理呢?

1.任何继承了NSObject的对象需要进行内存管理

2.而其他非对象类型(int\ char\ float\double\ struct\enum等)不需要进行内存管理,原因如下:

​ a,继承了NSObject的读象的存储在操作系统的堆里边

​ b.操作系统的堆:一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收,分配方式类似于链表

​ c.非OC对象一般放在操作系统的栈里面

​ d.操作系统的栈:由操作系统自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈(先进后出)

int a = 10;  //. 栈
int b = 20;  //  栈
  //. p : 栈
  //  Person对象(计数器 = 1) : 堆
Person *p = [[Person alloc] init];

// 经过上面的代码后,栈里的变量a\b\p都会被回收
//。但是堆里面的Person对象还会留在内存中,因为它时计数器依然是1

在这里插入图片描述

内存管理模型

提供给OC程序员的基本内存管理模型有以下3种:

​ 自动垃圾收集(ios运行环境不支持)

​ 手工引用计数和自动释放池(MRC)

​ 自动引用计数(ARC)

MRC手动管理内存(几乎不用了)

ARC自动管理内存

Automatic Reference Couting,自动引用计数,即ARC,WWDC2011和Ios5所引入的最大的变革和最激动人心的变化。ARC是新的LLVM3.0编译器的一项特性,使用ARC,可以说一举解决老人广大开发者所厌恶的手动内存管理的麻烦。

使用ARC后,系统会检测出何时需要保持对象,何时需要自动释放对象,编译器会关路好对象的内存,会在合适的地方插入retain,release和autorelease,通过生成正确的代码去自动释放或者保持对象。

1.ARC的判断一个对象是否需要释放不是通过引用计数来进行判断的,而是通过强指针来进行判断的。那么什么是强指针?

强指针

​ 默认所有对象的指针变量都是强指针

​ 被_strong修饰的指针

Person *p1 = [[Person alloc] init];
__strong Person *p2 = [[Person alloc] init];

弱指针

​ 被__weak修饰的指针

__weak Person *p = [[Person alloc] init];

ARC如何通过强指针判断?

​ 只要还有一个强指针变量指向对象,对象就会保持在内存中

2.ARC的使用

int main (int argc, const char * argv[]) {
	//. 不用写release,main函数执行完毕后p会被自动释放
	Person *p = [[Person alloc] init];
	return 0;
}

3.ARC的注意点

不允许调用对象的release方法

不允许调用autorelease方法

重写父类的dealloc方法时,不能再调用[super dealloc];

4.ARC下单对象内存管理

//. 局部变量释放对象随之被释放
int main(int argc, const char * argv[]) {
   @autoreleasepool {
        Person *p = [[Person alloc] init];
    } // 执行到这一行局部变量p释放
    // 由于没有强指针指向对象, 所以对象也释放
    return 0;
}

//。清空指针对象随之被释放
int main(int argc, const char * argv[]) {
  @autoreleasepool {
    	Person *p = [[Person alloc] init];
    	p = nil;
  }
  return 0;
}

//. 默认清空所有指针都是强指针
int main(int argc, const char *argv[]) {
  @autoreleasepool {
      //. p1和p2都是强指针
    	Person *p1 = [[Person alloc] init];
    	__strong Person *p2 = [[Person alloc] init];
  }
  return 0;
}

//. 弱指针需要明确说明
	// 注意:千万不要使用弱指针保存新创建的对象
//. p1是弱指针,对象会被立即释放
__weak Person *p1 = [[Person alloc] init];

5.ARC下多对象内存管理

​ ARC和MRC一样,想拥有每个对象必须用强指针保存对象,但是不需要在dealloc方法中release

6.ARC下@property参数

​ strong:用于OC对象,相当于MRC中的retain

​ weak:用于OC对象,相当于MRC中的assign

​ assign:用于基本数据类型,跟MRC中的assign一样

7.ARC下循环引用问题

​ ARC和MRC一样,如果A拥有B,B也拥有A,那么必须一方使用弱指针

@interface Person : NSObject
@property (nonatomic, strong) Dog *dog;
@end

@interface Dog : NSObject
// 错误写法, 循环引用会导致内存泄露
//@property (nonatomic, strong) Person *owner;

// 正确写法, 当如果保存对象建议使用weak
@property (nonatomic, weak) Person *owner;
@end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值