• Objective-C内存管理基础知识


    iOS的内存管理分为MRC和ARC

    内存管理原则:

    • 只要还有人在使用这个对象,那么这个对象就不会被回收;
    • 只要你想使用这个对象,那么就应该让这个对象的引用计数器+1;
    • 当你不想使用这个对象时,应该让对象的引用计数器-1;
    • 如果你通过alloc,new,copy来创建一个对象,那么你就必须调用release或者autorelease方法;
    • 只要你调用了retain,最后都要调用release。

    OC内存管理的范围:

    • 管理任何继承NSObject的对象,对其他的基本数据类型无效。内存管理主要是对堆区中对象的内存管理。本质原因是:对象存储于堆中,其它局部变量主要存放于栈中,当代码块结束,其中所有局部变量会被回收,指向对象的指针也会被回收,此时对象已经没有指针对象,但还存在于内存中,造成内存泄漏。

    @property的参数:

    •  读写属性:(readwrite、readonly)
    •  setter语意:(assign/retain/copy/strong/weak)
    •    原子性:(atomic/nonatomic)

    各参数意义如下:

    引用计数器的作用:

    • 引用计数器是判断对象要不要回收的依据(存在一种例外:对象值为nil时,引用计数为0,但不回收空间)。

    对引用计数器的操作

    • 给对象发送消息,进行相应的计数器操作。
    • retain消息:使计数器+1,该方法返回对象本身。
    • release消息:使计数器-1,并不代表释放对象
    • retainCount消息:获取对象当前的引用计数器值  %ld  

    三种方法可以增加对象引用计数器的值:

    • 显示使用alloc创建一个对象
    • 显示使用copy[WithZone:]或者mutableCopy[WithZone:]拷贝对象
    • 显示使用retain

    对象的销毁

    • 当一个对象的引用计数器为0时,那么它将被销毁,其占用的内存被系统回收。
    • 在OC中,实例方法dealloc用来释放对象中的实例变量指向的堆空间。
    • 当对象被销毁时,系统会自动向对象发送一条dealloc消息,一般会重写dealloc方法,在这里释放相关的资源。
    • 一旦重写了dealloc方法就必须调用[super dealloc];,并且放在代码块的最后。
    • 一旦对象被回收了,那么他所占据的存储空间就不再可用,坚持使用会导致程序崩溃。

    注意:

    • 如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不会被回收。
    • 任何一个对象,刚生下来的时候,引用计数器都为1。当使用alloc.new.copy创建一个对象时,对象的引用计数器默认为1

    自动释放池:

    • 自动释放池是OC的一种内存自动回收机制,可以将一些临时变量通过自动释放池统一回收释放
    • 每当一个对象接收到autorelease消息时,对象就会被放到自动释放池中,当自动释放池被释放时,他里面的对象会接收到一次release消息
    • 当一个对象接收到autorelease消息时,系统会把对象放到最近的自动释放池中。当需要清空自动释放池时,你可以向自动释放池发送一个release消息。
    • 简单来说,当向一个对象发送autorelease消息时,对象不会被立即释放。
    • 使用autorelease需要注意:首先,发送过多的autorelease消息,就和你发送太多的release一样,当清空自动释放池时,可能会引发内存故障。其次,虽然release消息可以被替换为autorelease,但是出于对系统性能的考虑,可以使用release的地方尽量不要使用autorelease,因为自动释放池所作的工作要比直接使用release多很多。最后,自动释放池的延迟释放机制可能会导致无用的内存消耗。
    • 在创建对象时,如果你没有使用alloc,则不需要使用release或者autorelease。但是如果你显示使用了alloc,则你不要忘记使用release或autorelease。
    • 当自动释放池释放时,自动释放池中的对象 可能 会被释放。这是因为,当自动释放池释放时,系统会给释放池中的每一个对象发送一个release消息,使得对象的引用计数器的值减1,如果对象引用计数器的值减为0了,则系统会向对象发送dealloc消息彻底销毁对象。

    autorelease缺点:

    • 不能精确控制对象被销毁的时间,拉长了对象的生命周期,内存处理效率降低。当不确定某个对象什么时候要释放时,或者操作的对象占用内存比较小时,可以用autorelease,但当操作占用内存比较大的对象时,要用release。一般情况下release优先使用。
  • 相关阅读:
    用track给视频添加字幕,浏览器被拦截 ,怎么解决?
    小区内公共车位物业管理公司是否有出租权 纵一苇之所如
    使用自动精灵在Android设备上重复播放语音500次
    移动端 持久化数据在客户端
    [go每日一库] go借助net/http包实现客户端get、post请求 Marathon
    [go每日一库] golang gin框架路由设置(全面) Marathon
    [go每日一库] golang中借助json等库实现struct和map互转 Marathon
    [go每日一库] golang validator参数校验 Marathon
    [go每日一库] go语言文件处理 Marathon
    [go每日一库] golang 通过os/exec执行shell命令 Marathon
  • 原文地址:https://www.cnblogs.com/s-y-j/p/5755957.html
Copyright © 2020-2023  润新知