IOS 基础知识 - 内存管理

内存管理原则

本小节知识点:

  1. 【掌握】内存管理原则
  2. 【掌握】多对象内存管理
  3. 【掌握】set方法内存管理
  4. 【掌握】dealloc方法的内存管理

1.内存管理原则

  • 苹果官方规定的内存管理原则

    • 谁创建谁release :

      • 如果你通过alloc、new、copy或mutableCopy来创建一个对象,那么你必须调用release或autorelease
    • 谁retain谁release:

      • 只要你调用了retain,就必须调用一次release
  • 总结一下就是

    • 有加就有减
    • 曾经让对象的计数器+1,就必须在最后让对象计数器-1

2.多对象内存管理

  • 单个对象的内存管理, 看起来非常简单

  • 如果对多个对象进行内存管理, 并且对象之间是有联系的, 那么管理就会变得比较复杂

  • 其实, 多个对象的管理思路 跟很多游戏的房间管理差不多

    • 比如斗地主 \ 劲舞团 \ QQ音速

在这里插入图片描述

  • 总的来说, 有这么几点管理规律
    • 只要还有人在用某个对象,那么这个对象就不会被回收
    • 只要你想用这个对象,就让对象的计数器+1
    • 当你不再使用这个对象时,就让对象的计数器-1

3.set方法内存管理

  • (1)retain需要使用的对象
  • (2)release之前的对象
  • (3)只有传入的对象和之前的不同才需要release和retain
- (void)setRoom:(Room *)room
{
    // 避免过度释放
    if (room != _room)
    {
        // 对当前正在使用的房间(旧房间)做一次release
        [_room release];

        // 对新房间做一次retain操作
         _room = [room retain];
    }
}

4.dealloc方法的内存管理

- (void)dealloc
{
    // 当人不在了,代表不用房间了
    // 对房间做一次release操作
    [_room release];
    [super dealloc];
}


野指针\空指针

本小节知识点:

  1. 【掌握】什么是僵尸对象
  2. 【掌握】什么是野指针
  3. 【掌握】什么是空指针

1.僵尸对象

  • 已经被销毁的对象(不能再使用的对象)

2.野指针

  • 指向僵尸对象(不可用内存)的指针
  • 给野指针发消息会报EXC_BAD_ACCESS错误

3.空指针

  • 没有指向存储空间的指针(里面存的是nil, 也就是0)

  • 给空指针发消息是没有任何反应的

  • 为了避免野指针错误的常见办法

    • 在对象被销毁之后, 将指向对象的指针变为空指针

引用计数器

本小节知识点:

  1. 【理解】什么是引用计数器
  2. 【理解】引用计数器的作用
  3. 【理解】引用计数器的操作

1.什么是引用计数器

  • 系统是如何判断什么时候需要回收一个对象所占用的内存?

    • 根据对象的引用计数器
  • 什么是引用计数器

    • 每个OC对象都有自己的引用计数器
    • 它是一个整数
    • 从字面上, 可以理解为”对象被引用的次数”
    • 也可以理解为: 它表示有多少人正在用这个对象

在这里插入图片描述

2.引用计数器的作用

  • 简单来说, 可以理解为:

    • 引用计数器表示有多少人正在使用这个对象
  • 当没有任何人使用这个对象时, 系统才会回收这个对象, 也就是说

    • 当对象的引用计数器为0时,对象占用的内存就会被系统回收
    • 如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收(除非整个程序已经退出 )
  • 任何一个对象, 刚生下来的时候, 引用计数器都为1

    • 当使用alloc、new或者copy创建一个对象时,对象的引用计数器默认就是1

3.引用计数器的操作

  • 要想管理对象占用的内存, 就得学会操作对象的引用计数器

  • 引用计数器的常见操作

    • 给对象发送一条retain消息,可以使引用计数器值+1(retain方法返回对象本身)
    • 给对象发送一条release消息, 可以使引用计数器值-1
    • 给对象发送retainCount消息, 可以获得当前的引用计数器值
  • 需要注意的是: release并不代表销毁\回收对象, 仅仅是计数器-1


@property参数

本小节知识点:

  1. 【掌握】控制set方法的内存管理
  2. 【掌握】控制需不需要生成set方法
  3. 【掌握】多线程管理
  4. 【掌握】控制set方法和get方法的名称

1.控制set方法的内存管理

  • retain : release旧值,retain新值(用于OC对象)
  • assign : 直接赋值,不做任何内存管理(默认,用于非OC对象类型)
  • copy : release旧值,copy新值(一般用于NSString *)

2.控制需不需要生成set方法

  • readwrite :同时生成set方法和get方法(默认)
  • readonly :只会生成get方法

3.多线程管理

  • atomic :性能低(默认)
  • nonatomic :性能高

4.控制set方法和get方法的名称

  • setter : 设置set方法的名称,一定有个冒号:

  • getter : 设置get方法的名称

  • 注意: 不同类型的参数可以组合在一起使用

循环retian

本小节知识点:

  1. 【掌握】循环retian基本概念

1.循环retian基本概念

  • 循环retain的场景

    • 比如A对象retain了B对象,B对象retain了A对象
  • 循环retain的弊端

    • 这样会导致A对象和B对象永远无法释放
  • 循环retain的解决方案

    • 当两端互相引用时,应该一端用retain、一端用assign

dealloc方法

本小节知识点:

  1. 【掌握】dealloc方法基本概念

1.dealloc方法基本概念

  • 当一个对象的引用计数器值为0时,这个对象即将被销毁,其占用的内存被系统回收

  • 对象即将被销毁时系统会自动给对象发送一条dealloc消息
    (因此, 从dealloc方法有没有被调用,就可以判断出对象是否被销毁)

  • dealloc方法的重写

    • 一般会重写dealloc方法,在这里释放相关资源,dealloc就是对象的遗言
    • 一旦重写了dealloc方法, 就必须调用[super dealloc],并且放在最后面调用
  • 使用注意

    • 不能直接调用dealloc方法
    • 一旦对象被回收了, 它占用的内存就不再可用,坚持使用会导致程序崩溃(野指针错误)

@class

本小节知识点:

  1. 【掌握】@class基本概念
  2. 【掌握】@class其它应用场景
  3. 【掌握】@class和#import

1.@class基本概念

  • 作用

    • 可以简单地引用一个类
  • 简单使用

    • @class Dog;
    • 仅仅是告诉编译器:Dog是一个类;并不会包含Dog这个类的所有内容
  • 具体使用

    • 在.h文件中使用@class引用一个类
    • 在.m文件中使用#import包含这个类的.h文件

2.@class其它应用场景

  • 对于循环依赖关系来说,比方A类引用B类,同时B类也引用A类
  • 这种嵌套包含的代码编译会报错
#import "B.h"
@interface A : NSObject
{
    B *_b;
}
@end

#import “A.h"
@interface B : NSObject
{
    A *_a;
}
@end

  • 当使用@class在两个类相互声明,就不会出现编译报错
@class B;
@interface A : NSObject
{
    B *_b;
}
@end

@class A;
@interface B : NSObject
{
    A *_a;
}
@end

3.@class和#import

  • 作用上的区别

    • #import会包含引用类的所有信息(内容),包括引用类的变量和方法
    • @class仅仅是告诉编译器有这么一个类, 具体这个类里有什么信息, 完全不知
  • 效率上的区别

    • 如果有上百个头文件都#import了同一个文件,或者这些文件依次被#import,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍 , 编译效率非常低
    • 相对来讲,使用@class方式就不会出现这种问题了

Xcode设置

本小节知识点:

  1. 【掌握】如何关闭ARC功能
  2. 【掌握】如何开启僵尸对象监控

1.如何关闭ARC功能

  • 要想手动调用retain、release等方法 , 就必须关闭ARC功能

在这里插入图片描述

2.如何开启僵尸对象监控

  • 默认情况下,Xcode是不会管僵尸对象的,使用一块被释放的内存也不会报错。为了方便调试,应该开启僵尸对象监控

在这里插入图片描述

在这里插入图片描述


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值