内存管理之MRCARC

MRC系列(二)MRC中HOST对错误的处理 MRC errors handle 阅读详情

内存管理

主要有以下四点:

  • 自己生成的对象,自己所持有
  • 非自己生成的对象,自己也能持有
  • 不再需要自己持有的对象就将其释放
  • 非自己持有的对象无法释放

对象操作与其Objective-C方法的对应:

对象操作Objective-C方法
生成并持有对象alloc/new/copy/mutableCopy方法
持有对象retain方法
释放对象release方法
废弃对象dealloc方法

分别介绍这四点:(代码均为MRC环境)

自己生成的对象,自己所持有

使用alloc/new/copy/mutableCopy方法

id obj = [[NSObject alloc] init];

以alloc/new/copy/mutableCopy为前缀的方法也可以

id obj = [NSObject newObject];

非自己生成的对象,自己也能持有

即使用alloc/new/copy/mutableCopy 以外的方法

id obj = [NSMutableArray array];

NSMutableArray的类对象赋值给obj,但NSMutableArray非obj自己生成且不持有,需要调用retain方法,即:

//取得的对象存在但不持有
id obj = [NSMutableArray array];
//持有该对象
[obj retain];

不再需要自己持有的对象就将其释放

自己持有的对象如果不需要了,有义务将其使用release方法释放

自己生成并持有的对象

//自己持有对象
id obj = [[NSObject alloc] init];
//释放对象
//指向对象的指针仍然被保留在变量obj中,貌似可以访问,但对象一经释放绝对不可访问
[obj release];

非自己生成并持有的对象

//取得的对象存在但不持有
id obj = [NSMutableArray array];
//持有该对象
[obj retain];
//释放对象
//对象不可再被访问
[obj release];

注意

在这里插入图片描述
注意 有可能会出现以上那种释放后还是可以访问的情况,那是因为obj指针依然存在并且指向那段内存,而内存还没有被占用,所以可以访问到,有时又会报错,相当于碰运气…

非自己持有的对象无法释放

如果不是自己持有的对象一定不能进行释放,倘若在应用程序中释放了非自己所持有的对象就会造成崩溃。

释放两次

例如自己生成并持有对象后,在释放完不再需要的对象之后再次释放(释放两次)

//自己生成并持有对象
id obj = [[NSObject alloc] init];
//释放对象
[obj release];
//释放对象
[obj release];

在这里插入图片描述
对象已经被释放了,即自己不持有了, 再次释放就会导致崩溃

本就不持有

取得的对象存在,但自己不持有对象时进行释放

id obj = [NSMutableArray array];
//释放非自己持有的对象,程序崩溃
[obj release];

在这里插入图片描述

retainCount

对象的引用计数可以用retainCount来取得
例如下面这段代码

//obj自己生成且持有该对象 retainCount+1 即为1
id obj = [[NSObject alloc] init];
NSLog(@"%lu", [obj retainCount]);
//obj1不持有该对象
id obj1 = obj;
//obj1持有该对象 retainCount+1 即为2
[obj1 retain];
NSLog(@"%lu", [obj retainCount]);
//obj1释放该对象 retainCount-1 即为1
[obj1 release];
NSLog(@"%lu", [obj retainCount]);

在这里插入图片描述
但是,我们在开发中不应使用此方法。该方法所返回的保留计数只是这一时间点的值,并没有考虑到系统会稍后把自动释放池清空,因而不会将后续的释放操作从返回值里减去,此值就未必是实际的数值了。例如这段代码:

while([obj retainCount]) {
	[obj release];
}

错误一:它没有考虑到后续的自动释放操作,只是不停地释放来降低保留计数。假如此对象也在自动释放池里,那么稍后系统清空自动释放池时就会崩溃
错误二:retainCount可能永远不返回0,有时系统会优化对象的释放行为,在保留计数还是1的时候就将对象回收,那么while循环永远不会停止。所以,就算有时可能正常运行也是靠运气。

autorelease

autorelease即“自动释放”,类似于C语言中的局部变量。C语言的局部变量:程序执行时,若某局部变量超出其作用域,该局部变量自动废弃。

{
	int a;
}
//此处超出变量a的作用域,局部变量a被废弃,不可再访问

autorelease像C语言的局部变量那样对待对象实例。当超出其作用域时,对象实例的release实例方法被调用,释放该变量。

使用方法

  • 生成并持有NSAutoreleasePool对象
  • 调用已分配对象的autorelease实例方法
  • 废弃NSAutoreleasePool对象

NSAutoreleasePool对象的生存周期相当于C语言变量的作用域。对于调用过autorelease方法的对象,在自动释放池废弃时,所有对象都将调用release方法

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
id obj = [[NSObject alloc] init];
[obj autorelease];
//执行该步时自动释放池中的对象释放
[pool drain];

适用场景

尽管NSAutoreleasePool会自动释放对象,但在大量产生autorelease对象并且自动释放池还没释放时,还是会生成大量对象,造成内存不足。举个例子,我们需要在读入大量图像的同时改变其尺寸。图像文件读入到NSData对象,生成UIImage对象,改变尺寸后生成新的UIImage对象。就会产生大量的autorelease对象。

for(int i = 0; i < 100000; i++) {
   //读入图像
   //产生autorelease对象
}

如果我们在循环体中加入自动释放池,即一个循环内会将生成的autorelease对象释放,内存就会节省很多

for(int i = 0; i < 100000; i++) {
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   //读入图像
   //产生autorelease对象
   //autorelease对象被释放
   [pool drain];
}

其他方法

Cocoa框架中也有很多类方法用于返回autorelease对象,比如:

id array = [NSMutableArray arrayWithCapacity:1];
//等效于
id array = [[[NSMutableArray alloc] initWithCapacity:1] autorelease];

我当时看到这里的时候有一个疑问:
第一个方法是arrayWithCapacity:很明显非array自己生成并且不持有,为什么说等同于第二句的alloc方法呢
因为第一个类方法返回的是autorelease对象,而第二个方法也调用了autorelease方法, 生成了autorelease对象,即返回值相同

showPools

可以通过自动释放池类中的调试用的showPools 方法来确认已经被autorelease的对象的状况。但是showPools方法只能在iOS中使用,现在我们使用非公开函数_objc_autoreleasePoolPrint()

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
id obj = [[NSObject alloc] init];
[obj autorelease];
extern void _objc_autoreleasePoolPrint(void);
_objc_autoreleasePoolPrint();
[pool drain];

在这里插入图片描述

使用showPools时使用showPools时

ARC自动引用计数

所有权修饰符

ARC有效时,id类型和对象类型必须附加所有权修饰符(默认为__strong),修饰符有四种:

  • __strong修饰符
  • __weak修饰符
  • __unsafe_unretained修饰符
  • __autoreleasing修饰符

__strong修饰符

__strong修饰符是默认的所有权修饰符,即:

id obj = [[NSObject alloc] init];
//等同于
id __strong obj = [[NSObject alloc] init];

__strong修饰符见名知意,表示对对象的“强引用”, 持有强引用的变量在超出其作用域时被废弃,随着强引用的失效,引用的对象会随之释放,即:

{
//因为变量obj为强引用,所以持有对象
	id __strong obj = [[NSObject alloc] init];
}
//超出作用域后强引用失效,对象所有者不存在,被自动释放

对于非自己生成的对象:

{
//因为变量obj为强引用,所以持有对象
	id __strong obj = [NSMutableArray array];
}
//超出作用域后强引用失效,对象所有者不存在,被自动释放

附有__strong修饰符的变量也可以互相赋值

id obj = [[NSObject alloc] init];
id obj2 = [[NSObject alloc] init];
id obj3 = nil;
obj3 = obj2;
obj2 = obj;

附有__strong修饰符同__weak修饰符,__autorelease修饰符一起,可以保证将附有这些修饰符的自动变量初始化为nil,即:

id __strong obj1;
id __weak obj2;
id __autoreleasing obj3;
//等同于
id __strong obj1 = nil;
id __weak obj2 = nil;
id __autoreleasing obj3 = nil;

__weak修饰符

__weak修饰符一般用于解决“循环引用”的问题,例如这段代码就会形成循环引用:

@interface MyObject : NSObject

@property (nonatomic) id object;

- (void)setObject:(id __strong) obj;

@end

@implementation MyObject 

- (instancetype)init
{
    self = [super init];
    return self;
}

- (void)setObject:(id __strong) obj {
    _object = obj;
}

@end

循环引用部分:

{
    id test1 = [[MyObject alloc] init];//对象A
    id test2 = [[MyObject alloc] init];//对象B
    [test1 setObject:test2];
    [test2 setObject:test1];
}

我们可以看出,持有对象A的变量为test1和test2的obj,同理,持有对象B的变量为test2和test1的obj
test1和test2超出作用域后,强引用失效,自动释放对象,但test1的obj和test2的obj都没有释放,发生内存泄漏!
这时候就需要用到__weak修饰符了,即弱引用。

id __weak obj = [[NSObject alloc] init];

如果直接这么写,编译器会报警告
在这里插入图片描述
因为__weak修饰符为弱引用,如果这么写就没有变量来持有新生成的对象,该对象一经生成就会自动释放,所以应该这么写:

id __strong sObj = [[NSObject alloc] init];
id __weak wObj = sObj;

让sObj持有它
上面的内存泄漏代码就可以改成:

@interface MyObject : NSObject
//将属性改为弱引用
@property (nonatomic) id __weak object;

- (void)setObject:(id __strong) obj;

@end

@implementation MyObject 

- (instancetype)init
{
    self = [super init];
    return self;
}

- (void)setObject:(id __strong) obj {
    _object = obj;
}

@end

__weak修饰符还有一好处就是,持有某对象的弱引用,如果对象被废弃,弱引用将自动失效且为nil

id __weak obj = nil;
{
	id obj0 = [[NSObject alloc] init];
    obj = obj0;
    NSLog(@"%@", obj);
}
NSLog(@"%@", obj);

在这里插入图片描述
附有__weak修饰符的变量,即是使用注册到自动释放池中的对象,证明:

    id obj = [[NSObject alloc] init];
    id __weak wObj = obj;
    NSLog(@"1 %@", wObj);
    NSLog(@"2 %@", wObj);
    NSLog(@"3 %@", wObj);
    NSLog(@"4 %@", wObj);
    NSLog(@"5 %@", wObj);
    _objc_autoreleasePoolPrint();

在这里插入图片描述
每访问一次会注册一次,当数量很多时,这样也会占据大量内存,就可以将附有__weak修饰符的变量赋值给附有__strong修饰符的变量后再使用可以避免此类问题

    id obj = [[NSObject alloc] init];
    id __weak wObj = obj;
    id tmp = wObj;
    NSLog(@"1 %@", tmp);
    NSLog(@"2 %@", tmp);
    NSLog(@"3 %@", tmp);
    NSLog(@"4 %@", tmp);
    NSLog(@"5 %@", tmp);
    _objc_autoreleasePoolPrint();

在这里插入图片描述
id tmp = wObj时对象仅注册到自动释放池中一次

__unsafe_unretained修饰符

正如其名,__unsafe_unretained修饰符是不安全的,且附有__unsafe_unretained修饰符的变量不属于编译器的内存管理对象
同样,附有__unsafe_unretained修饰符不能直接使用

id __unsafe_unretained obj = [[NSObject alloc] init];


与__weak修饰符不同的是:

id __unsafe_unretained obj = nil;
{
	id __strong obj0 = [[NSObject alloc] init];
	obj = obj0;
	NSLog(@"%@", obj);
}
NSLog(@"%@", obj);

在这里插入图片描述
原因是:obj变量既不持有对象的强引用也不持有对象的弱引用,当obj0失效时,对象无持有者,被释放,obj成为悬垂指针。故在使用__unsafe_unretained修饰符时一定要确保赋值的对象存在!

__autoreleasing修饰符

上面已经讲过ARC无效时autorelease的使用,在ARC有效时,可以写成这样:

@autoreleasepool {
	id __autoreleasing obj = [[NSObject alloc] init];
}

@autoreleasepool块即相当于上文的NSAutoreleasePool类生成、持有及废弃
附有__autoreleasing修饰符相当于变量调用了autorelease方法
以下为使用__weak修饰符的例子,虽然__weak修饰符是为了避免循环引用而使用的,但在访问附有__weak修饰符的变量时,实际上必定要访问注册到AutoreleasePool的对象

id __weak wObj = sObj;
NSLog(@"%@", [wObj class]);
//等同于
id __weak wObj = sObj;
id __autoreleasing tmp = wObj;
NSLog(@"%@", [tmp class]);

因为弱引用不持有,在访问对象的过程中对象有可能被废弃,要保证正常访问就需要将其注册到自动释放池中

一般情况下,id的指针或对象的指针会默认附加上__autoreleasing修饰符,即:

(NSError **)error
//等同于
(NSError * __autoreleasing *)error

然而,下面的源代码会有编译错误:

NSError *error = nil;
NSError **pError = &error;

在这里插入图片描述
赋值给对象指针时,所有权必须一致:

NSError *error = nil;
NSError * __strong *pError = &error;

在这里插入图片描述

一些规则

ARC有效时,不能使用retain或者release

只能在ARC无效时使用retain/release/retainCount/autorelease等方法
ARC有效时也不能使用NSAllocateObject/NSDeallocateObject函数

遵守命名规则

Objective-C对方法命名一直比较严格,但是对于ARC部分,必须遵守其命名规则,即:

  • 以alloc/new/copy/mutableCopy开始命名的方法在返回对象时,必须返回给调用方所应当持有的对象
  • 以init开始命名的方法在返回对象时,返回的对象应为id类型或该方法声明类的对象类型,抑或是该类的超类或子类

不要显示调用dealloc

使用@autoreleasepool块代替NSAutoreleasePool

不能使用区域

对象性变量不能作为C语言结构体的成员

要把对象型变量加入到结构体成员中时,可强制转换为void*或是附加__unsafe_unretained修饰符
但是附有__unsafe_unretained修饰符的变量不属于内存管理对象,使用时需要多注意

显式转换id和void*

如果只想单纯的赋值,则可以使用“__bridge转换”

id obj = [[NSObject alloc] init];
void *p = (__bridge void *)obj;
id o = (__bridge id)p;

__bridge转换中还有另外两种转换,“__bridge_retained转换”和“__bridge_transfer转换”
__bridge_retained转换可使要转换赋值的变量也持有所赋值的对象

id obj = [[NSObject alloc] init];
void *p = (__bridge_retained void *)obj;

__bridge_transfer转换提供与此相反的动作,被转换的变量所持有的对象在该变量被赋值给转换目标变量后随之释放
__bridge_retained转换同retain类似,__bridge_transfer转换同release类似

参考文献

《Objective-C高级编程 iOS与OS X多线程和内存管理》

iOS操作系统的内存泄漏检测与修复方法 内存泄漏的本质原理与发生机制主流检测工具的技术原理与操作范式不同编程范式(OC/Swift)下的修复最佳实践工程化场景中的自动化检测方案覆盖从基础内存管理模型到复杂框架集成场景,适用于iOS 9及以上版本开发环境。内存管理核心机制解析(MRC/ARC原理)泄漏检测工具链深度实践(Instruments全模块)数学模型与典型场景量化分析多语言环境下的修复策略(OC/Swift对比)工程化解决方案与最佳实践引用计数(Reference Counting) 阅读详情

相关推荐

台达PLC DIAdesigner-AX 编程笔记

1、登陆台达思图软件网站,选择Download,登陆注册好的账号,下载DIAInstaller,下载后安装(安装目录不要修改);

weixin_45823621的博客 6675

memory 异常处理

Memory 异常入口点 /*  * Data abort dispatcher  * Enter in ABT mode, spsr = USR CPSR, lr = USR PC  */     vector_stub    dabt, ABT_MODE, 8     .long    __dabt_usr            @  0  (USR_26 / USR_32

u011279649的专栏 5703

AI赋能软件测试:从冒烟测试到全流程智能化的效率革命

软件测试是确保软件质量的关键环节,其核心原理是通过预设用例验证系统功能是否符合预期。传统测试方法依赖人工编写和维护脚本,面临维护成本高、适应性差等挑战。随着人工智能技术的发展,特别是自然语言处理和计算机视觉的成熟,AI为测试领域带来了新的技术价值。通过让AI理解应用界面和业务逻辑,可以实现测试用例的智能生成、自主执行和结果分析,显著提升测试效率和覆盖率。在实际应用场景中,AI驱动的冒烟测试能够动态适应UI变化,自动分析失败日志,将测试人员从重复劳动中解放出来,专注于更复杂的质量策略设计。本文基于AI在冒烟测

weixin_28841265的博客 306

内存相关的几种常见问题_batch

H

chezabo6116的博客 302

信贷风控实战指南:Vintage分析表从数据建模到风险洞察

本文是一份信贷风控实战指南,详细阐述了Vintage分析从数据建模到风险洞察的全流程。文章深入解析了Vintage分析作为信贷资产“体检报告”的核心价值,并提供了从借据表与还款计划表设计、账龄计算、逾期口径判定到风险暴露计算与最终可视化透视的完整SQL实现方案,旨在帮助风控从业者构建精准的风险监控体系。

nft7creator的博客 321

Adobe Acrobat Pro(Adobe PDF) - 使用技巧

Adobe Acrobat Pro为Adobe出品的PDF查看和编辑软件,下文简称Adobe PDF,该软件功能强大,拥有查看PDF、编辑PDF、打印PDF、导出PDF、合并文件、组织页面、文本标注、注释、动作向导、等功能。本文介绍Adobe PDF的一些使用技巧,最后介绍软件设置。

NSJim的博客 4万+

黑马程序员 --- 内存管理的MRC和ARC

内存管理的MRC和ARC 内存管理 概念:  由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时,系统就会发出内存警告,个app可用的内存是被限制的,如果一个app使用的内存超过20M,则系统会向该app发送Memory Warning消息。收到此消息后,需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量,否则程序

u013644868的博客 1011

Vue2+OpenLayers动态绘制两个经纬度并计算距离(提供Gitee源码)

动态绘制两个经纬度并计算它们之间的距离。

黄团团的个人博客 366

Objective-C中的内存管理及MRC

本文主要介绍以下几部分: 一、内存管理的概念1、为什么要管理内存? 因为移动设备的内存极其有限,不回收不再使用的对象和变量会耗费内存使系统崩溃。2、Objective-C中内存管理的范围:管理任何继承自NSObject的对象。不管理基本数据类型。 因为基本数据类型储存在栈区,由系统管理;而OC对象存储在堆

yanggangclcsdn的博客 820

YOLOv8 交通违规检测各个场景的实际应用

本文介绍了基于YOLOv8的交通违规检测系统在不同场景下的应用实现。系统可检测闯红灯、超速、违停和不系安全带等多种违规行为,针对每种场景提供了具体的技术方案和Python实现代码。其中闯红灯检测结合信号灯状态分析,超速检测通过距离时间计算速度,违停检测采用长时间跟踪策略,安全带检测则需更高精度识别。文章还展示了如何整合各功能构建综合交通监管系统,并总结了不同应用场景的技术要点和优化方向,为智能交通管理提供了实用解决方案。

u010117029的博客 300

华为OD机试:查找接口成功率最优时间段 (C/C++/Py/Java/JS/GO)

华为OD机试双机位C卷 查找接口成功率最优时间段,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。

qq_45776114的博客 4687

【OC总结 面向对象 + 内存管理 + runtime】

面向对象 + 内存管理. + runtime总结 后续随时补充,总结为主,省略了一些源码实现runtime-运行时,是iOS系统的核心,它的本质是一套底层的C语言API。runtime将一些工作放在代码运行的时候才处理而非编译时为 Objective-C 语言的动态属性提供支持,所以很多的类和成员在我们编译的时候是不知道的,在运行时,所编写的代码会转换成完整的确定的代码运行。Apple - Objective-C 运行时。

weixin_61639290的博客 1026

2026年海能达嵌入式岗位面试题集(含参考答案)

本文总结了嵌入式系统开发中的常见面试题,涵盖项目经验、外设接口、存储系统、编程基础、操作系统等核心模块。主要内容包括:1)项目核心经历的硬件/软件架构及问题解决思路;2)SPI、I2C等接口协议的时序特点与应用要点;3)NAND Flash存储管理中的ECC校验原理和文件系统对接方案;4)USB设备枚举流程等关键知识点。这些题目针对嵌入式岗位的技术考察重点,既包含底层硬件接口细节,也涉及系统级设计与优化策略,全面考察开发者的嵌入式系统能力。

Open 360

Three20内存管理模式:ARC与MRC对比分析

Three20作为Objective-C的经典iOS开发库,其内存管理机制在不同编译环境下存在显著差异。本文将对比分析手动引用计数(MRC)与自动引用计数(ARC)在Three20中的实现方式,帮助开发者理解两种模式的核心差异及迁移策略。 ## 项目背景 Three20是Facebook开源的Objective-C库,曾广泛应用于iOS应用开发。根据[README.mdown](https://

gitblog_00789的博客 552

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

27-oc内存管理基本概念

堆和栈 栈(操作系统):由操作系统自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈(先进后出); 堆(操作系统):一般由程序员分配释放,若程序员不释放,程序结束时可能由系统回收,分配方式类似于链表。 内存管理 所谓内存管理,就是对内存进行管理,涉及的操作有: 分配内存:比如创建一个对象,会增加内存占用 清除内存...

185

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

内存管理初级

复习C语言中的内存: int *p = malloc(8); —>堆内存 free(p); free(p); —>过度释放 内存溢出: 内存不释放野指针: free之后还可以用p找到那块内存, 因为是标记删除; 但内存中内容不能保证还是原来的, 因为所有权已还给系统 野指针异常是程序crash主要原因 将ARC改为MRC: AR

Michael_Guess_Who的专栏 326

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

iOS笔记

iOS笔记内存管理MRCARC 内存管理 MRC ARC

appleios55的博客 200

【iOS】引用计数(一)

笔者最近开始学习了一下有关于引用计数的内容,写这篇博客来简单认识一下引用计数部分的内容。我们可以通过一个开关灯的思路去理解这部分内容,正如上图所展示的,我们办公室在第一个人来的时候就要开灯,在最后一个人走后就要关灯,不能在当一个人走后就进行一个关灯操作,这样会影响其他人工作,所以只有当最后一个人离开办公室的时候再关灯就好了,这样才可以让其他人正常工作,而我们创建的对象可以理解为办公室里的照明设备,只要有一个人工作,照明设备就不可以被关闭。OC中对应的一个状态对照明设备的操作生成对象开灯持有对象。

qq_73106050的博客 1578

strong,weak,assign,copy,retain的区别

版权声明:本文为延成原创文章,转载请标明出处 iOS内存管理 非OC对象(基础数据类型)存储在栈上 OC对象存储在堆上 他们区别就在于赋值时是否重新分配内存,引用计数是否变化。 在ARC条件下 (strong,weak, copy, assign) : strong: 表示指向并拥有该对象,不会开辟新的内存空间属于浅拷贝。其修饰的对象引用计数会增加1。该对象只要引用计数不为...

延成的博客 599

IOS开发之——单例-适配ARC和MRC(6)

一 概述 单例模式在ARC\MRC环境下的写法有所不同,需要编写2套不同的代码,可以用宏判断是否为ARC环境 #if __has_feature(objc_arc) //ARC #else //MRC #endif 二 几个概念 2.1 ARC和MRC Objective-c中两种内存管理机制ARC、MRC ARC(Automatic Reference Counting):自动内存管理 MRC(manual Reference Counting):手动内存管理 注意:Xcode4.1及其以前版本

我的博客 742

属性关键字

iOS属性关键字介绍

weixin_61196797的博客 911

ARC的工作原理

之前有学过一些关于ARC和MRC的东西,可以看。

weixin_61196797的博客 690

Foundation => Objective-C _ Part4

1. 内存管理 堆和栈 栈 (操作系统) : 由操作系统自动分配释放, 存放函数的参数值(形参),局部变量的值等. 其操作方式类似于数据结构中的栈 (先进后出) 堆 (操作系统) : 一般由程序员分配释放, 若程序员不释放, 程序结束时可能由OS回收, 分配方式类似于链表 只要是alloc init创造的, 都放在堆里 OC对象存放在堆里,堆里的数据系统不会自动释放, 需要手动释放 非OC对象一

狼的最爱的博客 2443

面试要点

KVO的详解 观察者设计模式 主要运用到系统的isa混写技术,系统会创建一个子类添加set方法 (NSKVONotifying_A)将创建的isa的指向系统创建的类。 KVC的详解 键值编码 KVC会破坏面向对象编程的封装特性。 KVC这里的key是没有任何限制的,如果已知某个类或者实例的内部某个私有成员变量名称的话,我们在外界是可以通过已知的key来访问、设置。即破坏了面向对象的编程思想 As...

weixin_43480652的博客 223

iOS的单例模式详解

单例设计模式确切的说就是一个类只有一个实例,有一个全局的接口来访问这个实例。当第一次载入的时候,它通常使用延时加载的方法创建单一实例。 苹果大量的使用了这种方法。例子: [UIApplication sharedApplication], [UIScreen mainScreen], [UIApplication sharedApplication]; (应用程序实例类);[NSNotificationCenter defaultCenter];(消息中心实例类);[NSF...

程序猿老樊的博客 2212

内存分区,编译链接,ARCMRC,消息传递消息转发,对象的底层

对第一周学习内容做个概括提示:以下是本篇文章正文内容,下面案例可供参考。

weixin_61196797的博客 416
上一篇: ERROR SparkContext: Error initializing SparkContext.
下一篇: ARC探究
Tuski-
博客等级 码龄8年 51粉丝 82原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值