首页 > 系统相关 >iOS开发-属性的内存管理

iOS开发-属性的内存管理

时间:2024-08-07 16:38:17浏览次数:9  
标签:示例 对象 iOS 计数 引用 属性 内存

Objective-C中,类的实例变量(instance variables)和属性(properties)是两种不同的概念,其中属性的内存管理就较为复杂。Objective-C 提供了多种属性修饰符,用于管理对象的内存。这些修饰符用于控制对象的生命周期和内存管理行为。

以下是一些常见的属性修饰符及其内存管理行为的详细介绍:

1. strong

  • 适用对象:通常用于对象类型(如 NSObject 及其子类)。
  • 内存管理strong 属性会对对象进行强引用计数。当一个对象被赋值给一个 strong 属性时,该对象的引用计数会增加 1。当这个属性被设置为 nil 或对象被释放时,引用计数会减少 1。
  • 生命周期:只要有一个 strong 引用指向对象,该对象就不会被释放。

示例

@property (nonatomic, strong) NSString *name;

在这个示例中,name 属性是一个 strong 引用,这意味着只要 name 属性指向的对象存在,引用计数就会增加,确保对象不会被释放。

2. weak

  • 适用对象:通常用于对象类型,特别是在避免循环引用时。
  • 内存管理weak 属性不会对对象进行强引用计数。当对象被释放时,weak 属性会自动设置为 nil,避免悬挂指针问题。
  • 生命周期weak 引用不会延长对象的生命周期。

示例

@property (nonatomic, weak) id<SomeDelegate> delegate;

在这个示例中,delegate 属性是一个 weak 引用,这意味着当 delegate 对象被释放时,delegate 属性会自动设置为 nil

3. assign

  • 适用对象:通常用于基本数据类型(如 intfloatBOOL)和非对象类型(如 NSIntegerCGFloat)。
  • 内存管理assign 属性不会对对象进行引用计数管理。它只是简单地赋值,不会增加或减少引用计数。
  • 生命周期:如果 assign 属性指向一个对象,当该对象被释放时,assign 属性不会自动设置为 nil,可能会导致悬挂指针(dangling pointer)问题。

示例

@property (nonatomic, assign) NSInteger age;

在这个示例中,age 属性是一个 assign 引用,这意味着它只是简单地存储一个整数值,不涉及引用计数管理。

4. copy

  • 适用对象:通常用于需要不可变副本的对象类型(如 NSStringNSArrayNSDictionary)。
  • 内存管理copy 属性会对对象进行浅复制或深复制,具体取决于对象的实现。当一个对象被赋值给一个 copy 属性时,会创建一个新的副本,并将其赋值给属性。
  • 生命周期copy 引用会创建一个新的对象副本,确保属性持有的对象是独立的。

示例

@property (nonatomic, copy) NSString *name;

在这个示例中,name 属性是一个 copy 引用,这意味着当一个对象被赋值给 name 属性时,会创建一个新的副本,并将其赋值给 name 属性。

5. unsafe_unretained

  • 适用对象:通常用于对象类型,但不推荐使用。
  • 内存管理unsafe_unretained 属性不会对对象进行强引用计数。当对象被释放时,unsafe_unretained 属性不会自动设置为 nil,可能会导致悬挂指针问题。
  • 生命周期unsafe_unretained 引用不会延长对象的生命周期。

示例

@property (nonatomic, unsafe_unretained) id delegate;

在这个示例中,delegate 属性是一个 unsafe_unretained 引用,这意味着当 delegate 对象被释放时,delegate 属性不会自动设置为 nil,可能会导致悬挂指针问题。

总结

  • strong:用于对象类型,增加引用计数,确保对象不会被释放。
  • weak:用于对象类型,不增加引用计数,当对象被释放时,属性自动设置为 nil
  • assign:用于基本数据类型和非对象类型,不涉及引用计数管理。
  • copy:用于需要不可变副本的对象类型,创建对象的副本。
  • unsafe_unretained:用于对象类型,但不推荐使用,不增加引用计数,当对象被释放时,属性不会自动设置为 nil

理解这些属性修饰符的区别才能更好地管理内存,避免内存泄漏和悬挂指针问题。

标签:示例,对象,iOS,计数,引用,属性,内存
From: https://www.cnblogs.com/jianqiu/p/18347358

相关文章

  • Python 循环引用与内存泄漏:深度解析
    Python循环引用与内存泄漏:深度解析在Python编程中,循环引用和内存泄漏是两个需要特别注意的问题。本文将深入探讨Python中的循环引用现象、其导致的内存泄漏问题,并提供详细的解决思路与方法。同时,我们还将分析一些常见场景,并分享扩展与高级技巧,帮助读者全面理解和应对这一......
  • iOS app启动优化
    app的启动阶段可分为main函数调用前和main函数调用后,分别都做了些什么呢1、pre-main阶段   1)加载应用的可执行文件(自身App的所有.o文件的集合)  2)加载动态链接器dyld(dynamicloader,是一个专门用来加载动态链接库的库)  3)dyld递归加载应用所有依赖的动态链接库dyli......
  • 内存重叠以及memcpy和memmove函数详解
    内存重叠当我们进行内存拷贝(memcpy函数)时或者在自己实现内存拷贝函数strcpy时,如果存在目标地址在原地址的范围内就造成了内存重叠。一开始看到这个名词的时候,确实有点难以理解,经过学习,我利用以下的例子来说明内存重叠问题。首先,先介绍一下memcpy和memmove函数memcpy和mem......
  • <转载>bios 关机过程
    [CSDNBIOS关机过程](https://blog.csdn.net/robinsongsog/article/details/50993333)热启动,冷启动,关机,这些词相信大家都很熟悉,今天就从BIOS的角度,说说这三种reset具体是怎么实现的。/**Resetthesystem.@paramResetTypewarmorcold@paramResetStatus......
  • 如何缓存可变实例属性?
    我可以像这样缓存数据类的实例属性:fromdataclassesimportdataclassfromfunctoolsimportcached_property@dataclassclassPoint:_x:float@cached_propertydefx(self):returnself._x*2>>p=Point(3)>>p.x6我希望每次调用它时......
  • 【VMware ESXi】把硬盘当内存用?VMware 内存分层(Memory Tiering),你值得拥有!
    VMwarevSphere8.0U3发布了一个非常有意义的功能叫内存分层(MemoryTiering),以利用基于PCIe的NVMe设备充当第二层(辅助)内存,从而使ESXi主机的可用物理内存(RAM)增加。从本质上讲,内存分层就是利用较便宜的NVMe设备充当物理内存,以此增加内存的总容量和工作负载的可用量,同时降低......
  • uniapp 在微信H5、安卓、IOS预览PDF
    前言uniapp在微信内通过链接预览PDF,而现有uniapp插件都是通过在线网站解析例如:mumu-previewOffce但解析网站目前已经不能访问准备工作下载PDF.JShttps://github.com/mozilla/pdf.js/releases/download/v2.4.456/pdfjs-2.4.456-dist.zip放置在uniapp根目录static下并自......
  • 图像识别与处理之Opencv——Mat_类与Mat 类的内存管理
    Mat_类Mat_类是对Mat类的一个包装,其定义如下点击查看代码template<typename_Tp>classMat_:publicMat{public://只定义了几个方法//没有定义新的属性};这是一个非常轻量级的包装,既然已经有Mat类,为何还要定义一个Mat_类?下面我们看这段代码:点击查看代码Ma......
  • Vue初识,vue的插值语法,vue指令之文本指令,vue指令之事件指令, vue指令之属性指令
    ⅠVue初识【一】前端的发展史#1HTML(5)、CSS(3)、JavaScript(ES5、ES6、ES13):编写一个个的页面->给后端(PHP、Python、Go、Java)->后端嵌入模板语法->后端渲染完数据->返回数据给前端->在浏览器中查看#2Ajax的出现->后台发送异步请求,Render+Ajax混合#3单......
  • Day18_2--Vue.js Ajax(使用 Axios)基础入门学习
    Vue.js中的Ajax请求(使用Axios)什么是Axios?Axios是一个基于Promise的HTTP客户端,可以用于浏览器和Node.js环境中。它是现代化的Ajax库,用来替代传统的XMLHttpRequest。为什么选择Axios?简单易用:Axios提供了简洁且强大的API,使得发送HTTP请求变得非常简单......