iOS经典讲解之Objective-C属性的内存管理原理

深入理解Objective C的ARC机制 从Runtime源码和汇编的角度深入挖掘ARC的本质 阅读详情


@在进行讲解属性的内存管理之前,先来看看之前我们使用实例变量时是怎样管理内存的:

我们创建两个相关联的类Person类和Pet类,来看看它们中的赋值和取值方法是怎样管理内存的:

Pet.h

#import <Foundation/Foundation.h>

@interface Pet : NSObject
{
    
    NSString *_name;
}

// 声明赋值 取值方法
- (void)setName:(NSString *)name;
- (NSString *)name;

@end
Pet.m
#import "Pet.h"

@implementation Pet

// 实现赋值 取值方法
- (void)setName:(NSString *)name
{
    if (_name != name) {
        [_name release];
        // 字符串一般用copy
        _name = [name copy];
        
    }
    
}
- (NSString *)name
{
    return _name;
}

// 释放实例变量
-(void)dealloc
{
    [_name release];
    [super dealloc];
}

@end
Person.h
#import <Foundation/Foundation.h>
#import "Pet.h"

@interface Person : NSObject
{
    // 声明三个不同类型的实例变量
    Pet *_pet;
    NSString *_name;
    NSInteger _age;
}
// 声明赋值 取值方法
- (void)setPet:(Pet *)pet;
- (Pet *)pet;
- (void)setName:(NSString *)name;
- (NSString *)name;
- (void)setAge:(NSInteger)age;
- (NSInteger)age;
// 测试方法
- (void)test;


@end
Person.m
#import "Person.h"

@implementation Person

// 实现赋值 取值方法
- (void)setPet:(Pet *)pet
{
    if (_pet != pet) {
        [_pet release];
        // 对象类型使用retain获得所有权,然后在dealloc方法中释放
        _pet = [pet retain];
    }
}
- (Pet *)pet
{
    return _pet;
}
- (void)setName:(NSString *)name
{
    if (_name != name) {
        [_name release];
        // 字符串一般使用copy获得所有权,然后在dealloc方法中释放
        _name = [name copy];
    }
}
- (NSString *)name
{
    return _name;
    
}
- (void)setAge:(NSInteger)age
{
    // 基本数据类型不需要管理内存,因为不涉及引用计数的变化
    _age = age;
}
- (NSInteger)age
{
    return _age;
}
// 实现测试方法
- (void)test
{
    NSLog(@"%@:我今年%ld岁,我有只宠物叫%@", _name, _age, [_pet name]);
}
// 释放实例变量
-(void)dealloc
{
    [_name release];
    [_pet release];
    [super dealloc];
}

@end
接下来我们来看看属性是怎么写的:大家知道使用属性系统会自动声明并实现赋值(setter)和取值(getter)方法,不需要我们再来声明和实现赋值和取值方法,并且还自动给我们声明了带下划线的实例变量,给我们开发带来了极大的方便。虽然不需要我们再来操作赋值和取值方法,那他的实现原理我们还是要做到心中明白的。

属性是怎样管理内存的首先属性的语义控制类型:

语义控制:assign、copy、retain。assign一般用于非对象类型和代理(如int, float等),retain(对象类型,如NSDictionary、NSArray)会使属性的引用计数加1,一般对象使用retain。copy如果想得到对象的副本,那么这个时候使用copy。默认是assign。

当使用assign时:就如同上面的对实例变量age的赋值方法

- (void)setAge:(NSInteger)age
{
    // 基本数据类型不需要管理内存,因为不涉及引用计数的变化
    _age = age;
}
当使用copy时,就如同上面的对实例变量name的赋值方法

- (void)setName:(NSString *)name
{
    if (_name != name) {
        [_name release];
        // 字符串一般使用copy获得所有权,然后在dealloc方法中释放
        _name = [name copy];
    }
}
当使用retain时就如同上面对实例变量pet的赋值方法

- (void)setPet:(Pet *)pet
{
    if (_pet != pet) {
        [_pet release];
        // 对象类型使用retain获得所有权,然后在dealloc方法中释放
        _pet = [pet retain];
    }
}
对于使用实例变量的代码用属性来替换的话,代码量缩短很多,下面替换上面的代码。

Pet.h

#import <Foundation/Foundation.h>

@interface Pet : NSObject

@property (nonatomic, retain) NSString *name;

@end
Pet.m
#import "Pet.h"

@implementation Pet

// 释放属性
-(void)dealloc
{
    [_name release];
    [super dealloc];
}

@end
Person.h
#import <Foundation/Foundation.h>
#import "Pet.h"

@interface Person : NSObject

@property (nonatomic, retain) Pet *pet;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;

// 测试方法
- (void)test;

@end
Person.m
#import "Person.h"

@implementation Person

// 实现测试方法
- (void)test
{
    NSLog(@"%@:我今年%ld岁,我有只宠物叫%@", _name, _age, [_pet name]);
}
// 释放属性
-(void)dealloc
{
    [_name release];
    [_pet release];
    [super dealloc];
}

@end
注意:如果使用属性,重写set和get方法时,系统会找不到相应的实例变量,这时需要重新声明实例变量,如果重写其中一个则不需要。



重读2007年Objective-C前言:iOS开发的底层契约与精神源流 Objective-C是苹果早期iOS生态的基石语言,其核心在于C语言的底层控制力与Smalltalk面向对象思想的融合。它通过Runtime动态消息机制、toll-free bridging跨框架互通、协议(Protocol)驱动的鸭子类型等设计,构建了高度灵活又强约束的开发范式。这种‘契约优先’的思想深刻影响了后续Swift的内存所有权模型、Delegate向AsyncSequence的演进,以及UIKit到SwiftUI的架构迁移。理解Objective-C并非怀旧,而是掌握iOS平台级开发的本质逻辑 阅读详情

相关推荐

Objective-C对象间内存管理深度解析与实战

在自定义UIView或业务组件时,我们也常需定义自己的代理协议。此时应严格遵循以下三条黄金法则:代理属性必须使用weak代理方法调用前必须检查是否为nil避免在代理方法中同步触发可能导致自身销毁的操作来看一个标准实现:@end@end@end逐行分析:协议继承自NSObject,支持检查;delegate声明为weak,防止反向强引用;调用前判断方法是否存在,提升健壮性;ARC会自动处理weak指针为nil的情况,不会crash。

weixin_35755434的博客 1095

ObjectiveC基础——封装、@property和点语法

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-一、概述 面向对象的三个特性是:封装、继承、多态。 不封装的缺陷:当一个类把自己的属性暴露给外部的时候,该类就失去了对属性的管理权。 一个类,将自身的属性对外隐藏起来,只有通过此类提供的方法才能访问或设置实例变量,不可被外部任意调用或修改,这种机制叫做封装。 封装可以提高类的安全性,降低数据被误用的可能性。

u010201701的博客 724

Objective-C编程完全自学指南最新版.pdf

Objective-C,作为iOS和Mac应用开发的核心语言之一,拥有丰富的编程范式和成熟的生态系统。本章旨在为读者提供一个宏观的视角,涵盖Objective-C的历史、特点以及与其它编程语言的对比。类的定义在Objective-C中是通过接口文件(通常以.h扩展名表示)来完成的。接口文件声明了类的属性和方法。实现文件(以.m扩展名表示)则包含了类的实现,即属性和方法的具体逻辑。

weixin_34945060的博客 756

IOS开发系列—Objective-C之内存管理

概述 我们知道在程序运行过程中要创建大量的对象,和其他高级语言类似,在ObjC中对象时存储在堆中的,系统并不会自动释放堆中的内存(注意基本类型是由系统自己管理的,放在栈上)。如果一个对象创建并使用后没有得到及时释放那么就会占用大量内存。其他高级语言如C#、Java都是通过垃圾回收来(GC)解决这个问题的,但在OjbC中并没有类似的垃圾回收机制,因此它的内存管理就需要由开发人员手动维护。今天将着重介

Kenshin Cui's Blog 1604

深入理解iOS 7编程基础与Objective-C

本文深入探讨了iOS 7编程基础和Objective-C语言的核心概念、技术及最佳实践。通过理解Xcode项目的创建、管理和调试,以及Cocoa Touch框架的深入学习,读者可以获得编写高质量iOS应用所需的坚实基础。

weixin_28487725的博客 479

OpenEuler内核编译及替换

一、内核源码下载 在gitee上下载OpenEuler内核源码 下载地址 选择需要的内核版本源码压缩包进行下载 二、内核编译 1.解压缩 将下载好的源码进行解压 tar xvf openeuler-kernel-4.19.90-2107.1.0.tar.gz 2.清理源代码树 解压后得到一个名为kernel的内核源码文件夹,进入后执行命令 make mrproper 清理过去内核编译产生的config,第一次编译时可不执行此命令 3.生成内核配置文件.config 先将将系统原配置文件拷贝过来,原

m0_56602092的博客 2万+

Objective-C 内存管理机制

一、Objective-C内存管理的对象。二、为什么要使用内存管理。三、Objective-C管理内存的方式。四、与内存有关的修饰符。五、MRC与ARC混编

lover0920的专栏 3292

保姆级教程:用Arduino+MPU6050自制寻北仪(附MEMS陀螺精度测试报告)

本文提供了一份详细的Arduino与MPU6050自制寻北仪的保姆级教程,包括硬件选型、卡尔曼滤波算法优化、地磁场补偿及真北计算等关键技术。通过实测数据展示了MEMS陀螺仪在民用领域的高精度性能,帮助读者低成本实现1°以内的寻北精度。

weixin_42522964的博客 364

【Effective Objective-C】—— 内存管理

第29条:理解引用计数 OC使用引用计数来管理内存,也就是说,每个对象都有个可以递增或递减的计数器,如果某个对象引用他时就会给其引用计数加1,用完了之后,就递减其计数,直至为0,销毁这个对象。ARC实际上也是一种引用计数机制。 1.引用计数工作原理: 在引用计数架构下,对象有个计数器,用以表示当前有多少个事物想令此对象继续存活下去。NSObject协议声明了下面三个方法用于操作计数器: Retain 递增保留计数 release 递减保留计数 autorelease 待稍后清理“自动释放池”时,再递减

m0_55124878的博客 2421

用Charles抓包调试iOS应用?这份保姆级配置指南帮你绕过所有坑

本文提供了一份在Mac上使用Charles抓包调试iOS应用的保姆级配置指南。详细讲解了从Charles安装、Mac端代理设置、根证书安装,到iOS设备连接同一WiFi、配置代理以及最关键的系统证书信任等全流程步骤,并分享了SSL代理规则、断点调试等进阶技巧,帮助开发者高效定位和解决网络请求问题。

rice5的博客 640

WeDetect:基于视觉-语言检索的目标检测新范式

目标检测正从传统回归与分类耦合范式,向开放、灵活、可扩展的多模态检索范式演进。检索式检测(Retrieval-based Detection)将检测任务重构为视觉特征与文本语义的联合匹配过程,依托候选框索引库与双塔架构,天然支持开放词汇、零样本识别与小目标定位。其技术价值在于解耦空间感知与语义理解,消除NMS与anchor匹配等冗余计算,显著提升推理效率与跨场景泛化能力。典型应用场景包括工业质检中的缺陷新增识别、遥感图像小目标检测、低光照鲁棒视觉系统等。WeDetect正是这一范式的代表性实现,深度融合视觉

weixin_30878501的博客 363

Objective-C Block 底层原理深度解析

Block 是 Objective-C 中的特殊对象,通过 isa 指针继承自 NSObject,实现了匿名函数的功能。它有三种类型:全局 Block(不捕获变量,存储在数据区)、栈 Block(捕获变量,存储在栈上)和堆 Block(由栈 Block 复制而来,存储在堆上)。Block 可以捕获变量,对于基本类型采用值复制,使用__block修饰符可以修改捕获的变量,对象类型默认是强引用。在内存管理方面,Block 遵循 Objective-C 的内存管理规则,需要注意循环引用问题,可以通过__weak。

画个大饼的博客 2646

CocosCreator 面试题(十五)Cocos Creator如何内置protobuf JS版本?

接着,它创建了一个 Player 对象,并使用 protobuf.js 提供的 API 对其进行序列化和反序列化操作。其中,name 和 level 是普通的字段,items 是一个 repeated 字段,表示它可以包含多个值。在 Cocos Creator 中使用 protobuf.js,我们需要先加载 .proto 文件,然后使用 protobuf.js 提供的 API 进行序列化和反序列化操作。JSON和XML是文本格式,更易于阅读和调试,而且在对人类友好的接口和数据交换上更为常见和广泛支持。

w风雨无阻w的专栏 2628

iOS开发系列—Objective-C之内存管理

概述 我们知道在程序运行过程中要创建大量的对象,和其他高级语言类似,在ObjC中对象时存储在堆中的,系统并不会自动释放堆中的内存(注意基本类型是由系统自己管理的,放在栈上)。如果一个对象创建并使用后没有得到及时释放那么就会占用大量内存。其他高级语言如C#、Java都是通过垃圾回收来(GC)解决这个问题的,但在OjbC中并没有类似的垃圾回收机制,因此它的内存管理就需要由开发人员手动维护。今天将着重

counting stars的博客 363

EB Tresos激活失败?3种实用解决方案帮你搞定(含离线激活步骤)

本文针对EB Tresos软件激活失败问题,提供了三种实用的解决方案。详细分析了激活失败的常见根源,并系统阐述了在线环境下的排查步骤、无网环境下的离线激活全流程,以及高级许可证环境修复方法,帮助汽车电子工程师快速恢复开发环境。

milk8的博客 609

YOLO系列专栏(十二):YOLO26行业落地实战(三):无人机航拍场景——户外巡检(机载边缘计算+YOLO26)

无人机航拍巡检场景,面临机载设备算力/显存有限、高空航拍目标小、户外环境复杂(风力、光线变化)、图像抖动等问题,对模型的轻量化、实时性、小目标检测能力要求极高。YOLO26相比传统模型,在该场景中具备三大核心优势:✅ 极致轻量化:INT8量化+模型剪枝后,模型体积可压缩至5MB以内,显存占用控制在512MB以内,适配Jetson Xavier NX等机载边缘计算设备;✅ 小目标检测能力强:优化检测头与锚框配置,可精准识别高空航拍中的小尺寸目标(如线路断股、绝缘子裂纹),检测准确率高;

qq_36130719的博客 260

【Effective Objective-C】内存管理

文章目录前言理解引用计数引用计数工作原理属性存取方法中的内存管理自动释放池保留环要点以ARC简化引用计数 前言 在OC这种面相对象的语言里,内存管理是个重要概念。要想用一门语言写出内存使用效率高而且又没有bug代码,就得掌握其内存管理模型的种种细节。 一旦理解了这些规则,你就会发现,其实OC的内存管理没那么复杂,而且有了“自动引用计数”(Automatic Reference Counting,ARC)之后,就变得更为简单了。ARC几乎把所有内存管理事宜都交由编译器来决定,开发者只需专注于业务逻辑。 理

kochunk1t的博客 1900

ICC2: 如何让CTS指定pin多长指定长度

这里create_clock不需要写到sdc里,在脚本里写就行,需要注意的是脚本里存在remove_clock_tree的话,add_buffer就要放remove_clock_tree后面,或者给guide buffer设don't touch也行。跟innovus的操作逻辑一样,如果要让tree上的某一点长长,要先考虑这个点后面的clock tree能正常balance。我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?-5意味着长长5ns,相反正值意味着做短。

m0_61544122的博客 680

【Effective Objective-C】——内存管理

文章目录理解引用计数参考博客:引用计数工作原理属性存取方法中的内存管理自动释放池保留环以ARC简化引用计数使用ARC时必须遵循的方法命名规则变量的内存管理语义ARC如何清理实例变量覆写内存管理方法在dealloc方法中只释放引用并解除监听编写“异常安全代码”时留意内存管理问题以弱引用避免保留环以“自动释放池块”降低内存峰值用“僵尸对象”调试内存管理问题不要使用retainCount 理解引用计数 参考博客: 【iOS开发】—— 自动引用计数初步学习 【iOS开发】——引用计数的简单了解 引用计数工作原理 在

weixin_50990189的博客 1907

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

黑马程序员-iOS基础-Objective-C基础(六)内存管理

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 黑马程序员-iOS基础-Objective-C基础(六)内存管理 一、内存管理的必要性 移动设备内存空间极其有限 app占用内存较多时,系统会发出内存警告,必须回收一些不需要再使用的内存 二、内存管理的范围  任何继承了NSObject的对象  对其他基本数据类型、struct

deng0512的专栏 634

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Swift与iOS内存管理机制深度剖析

内存管理是每一位 iOS 开发者都绕不开的话题。虽然 Swift 的 ARC(自动引用计数)极大简化了开发者的工作,但只有深入理解其底层实现,才能写出高效、健壮的代码,避免各种隐蔽的内存问题。本文将从底层原理出发,系统梳理 Swift 与 iOS 的内存管理机制,结合实战经验,分享常见问题与优化建议。

画个大饼的博客 1759

ios学习路线 -- objective-c 基础

摘要:Objective-C(OC)是一种面向对象的C语言扩展,其文件扩展名包括.h(头文件)、.m(OC/C代码)和.mm(支持C++)。OC语法除面向对象特性外与C语言一致,消息传递采用动态运行时机制。字符串处理通常使用NSString对象,类通过@interface声明和@implementation实现,支持方法重写和嵌套消息。属性(@property)简化了存取方法定义,支持多种内存管理修饰符(strong/weak/copy等)。协议(Protocol)定义方法列表,分类(Category)可扩

wjm041006的博客 1714

iOS——内存管理

要想用OC写出内存使用效率高而且又没有 bug 的代码,就得掌握其内存管理模型的种种细节。
一旦理解了这些规则,你就会发现,其实 Objective-C 的内存管理没那么复杂,而且有了"自动引用计数"(Automatic Reference Counting,ARC)之后,就变得更为简单了。ARC 几乎把所有内存管理事宜都交由编译器来决定,开发者只需专注于业务逻辑。 一 理解引用计数 OC语言使用引用计数来管理内存,也就是说,每个对象都有个可以递增或者递减的计数器。如果想使某个对象继续存活,那就增加其引用计

chabuduoxs的博客 1783

IOS开发系列—Objective-C之内存管理

本文转自:Kenshin Cui's Blog 概述 我们知道在程序运行过程中要创建大量的对象,和其他高级语言类似,在ObjC中对象时存储在堆中的,系统并不会自动释放堆中的内存(注意基本类型是由系统自己管理的,放在栈上)。如果一个对象创建并使用后没有得到及时释放那么就会占用大量内存。其他高级语言如C#、Java都是通过垃圾回收来(GC)解决这个问题的,但在OjbC中并没有类

江湖两把刀的技术博客 1526

Objective-C_内存管理(一)

一、内存管理的⽅式大家都去过图书馆,而图书馆里的书是可以借出的。我们来设想这样一个场景,大家都去借书,但是从来没有人去还书,那么最后,这个图书馆会因为无书可借而倒闭,每个人都没法再使用图书馆。计算机也是这样,当程序运行结束时,操作系统将回收其占用的资源。但是,只要程序运行就会占用资源,如果不进行清理已经不用的资源,资源最终将被耗尽,程序将崩溃。学会内存管理我们就明白什么时候由你释放对象,什么时候你不

谁见过风的专栏 1038
上一篇: iOS经典讲解之Objective-C关联对象的内存管理
下一篇: iOS经典讲解之Xcode开发不可不知的快捷键(新)
刘新林
博客等级 码龄11年 72粉丝 61原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值