Objective-C中的内存管理
在编程语言中是少不了对内存的管理的,内存对于计算机来说是宝贵的资源,所以对使用不到的资源进行回收是很有必要的。OC中使用引用计数和垃圾回收来管理内存,在OC中为每个对象分配一个引用计数器,当对象刚刚被创建时其初始值为1,当有某段代码需要访问一个对象是时,会将该对象的引用计数器加1(通过retain来实现);当访问一个对象结束时,会将该对象的引用计数器减1(通过release来实现);当计数器为0时,该对象占用的内存空间会被收回。在NSObject类有一个retainCount方法,调用该方法可获取当前对象的引用计数值。
在XCode4以后的版本采取自动引用计数(Automatic Reference Counting)简称ARC, 默认的是ARC模式,在ARC下是不能直接调用retain,release, releaseCount等方法的,需要在XCode中进行设置,设置如下: 把Objective-C Automatic Reference Counting 改为NO,即可。
之前提到的NSOject类里有个方法,retainCount可以获取当前对象的引用计数的值,废话少说上点代码吧。
1. 用可变的数组结合着可变的字符串来观察一下retainCount的变化。
(1).先创建一个可变数组对象,在创建一个可变字符串对象;
(2).然后往可变数组里添加可变的字符串,观察可变字符串的retainCount的变化。
(3).在可变数组中移除一个str,观察retainCount的变化
(4)我们为什么要用可变的字符串呢?稍后会提到为什么。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//用可变数组来测试内存的访问 NSMutableArray *array = [NSMutableArray arrayWithCapacity:3]; //可变的字符串 NSMutableString *str = [[NSMutableString alloc] initWithString:@ "aa" ]; //这时的retain = 1; NSLog(@ "新建str时的 strRetain = %d" ,( int )[str retainCount]); //把可变字符串对象传入到可变数组中 NSMutalbe的retain会自动加一 //把对象传给另一个对象,此时的retain = 2; [array addObject:str]; //retain =3; [array addObject:str]; NSLog(@ "添加两个str元素后 strRetain = %d" ,( int )str.retainCount); //移除元素 [array removeObjectAtIndex:0]; NSLog(@ "移除一个元素后 strRetain = %d" ,( int )str.retainCount); |
运行的结果:
1
2
3
|
2014-08-03 19:53:24.449 Memory[2448:303] 新建str时的 strRetain = 1 2014-08-03 19:53:24.449 Memory[2448:303] 添加两个str元素后 strRetain = 3 2014-08-03 19:53:24.450 Memory[2448:303] 移除一个元素后 strRetain = 2 |
2.NSString的retainCount的变化
用NSString声明的字符串变量的retainCount变化由你初始化字符串时的方式决定
1. 用NSString *str = @"ludashi";定义变量
用上面的方法定义的字符串是常量字符串,他的retianCount为-1或不定,不会随着retian或者release变化而变化
demo如下:
1
2
3
4
|
NSString *string = @ "aa" ; NSLog(@ "str常量的retainCount = %d" ,( int )string.retainCount); //retainCount = -1 [string retain]; //没用 NSLog(@ "str常量的retainCount = %d" ,( int )string.retainCount); //retainCount = -1 |
运行结果:
1
2
|
2014-08-03 20:01:31.360 Memory[2463:303] str常量的retainCount = -1 2014-08-03 20:01:31.362 Memory[2463:303] str常量的retainCount = -1 |
2.使用stringWithFormat创建的NSString为变量,系统会进行引用计数。
demo:
1
2
3
4
|
/*使用stringWithFormat创建的NSString为变量,系统会进行引用计数。*/ NSString *string1 = [NSString stringWithFormat:@ "aaaa" ]; [string1 retain]; NSLog(@ "NSStringFomatRetainCount = %d" ,( int )string1.retainCount); //retainCount = 2 |
运行结果:
1
|
NSStringFomatRetainCount = 2 |
3 .stringWithString取决于后面跟的string, 后面string的retainCount是多少那么用stringWithString创建的对象就为多少
demo:
1
2
3
4
5
6
7
|
/*stringWithString取决于后面跟的string, 后面string的retainCount是多少那么用stringWithString创建的对象就为多少*/ NSString *string2 = [NSString stringWithString:string]; NSLog(@ "传入字符串常量 RetainCount = %d" , ( int )string2.retainCount); //retainCount = -1 NSString *string3 = [NSString stringWithString:string1]; NSLog(@ "传入的变量FomatRetainCount = %d" ,( int )string1.retainCount); //retainCount = 3 NSLog(@ "传入的变量RetainCount = %d" , ( int )string3.retainCount); //retainCount = 3 |
运行结果:
1
2
3
|
2014-08-03 20:18:37.240 Memory[2499:303] 传入字符串常量 RetainCount = -1 2014-08-03 20:18:37.240 Memory[2499:303] 传入的变量FomatRetainCount = 3 2014-08-03 20:18:37.240 Memory[2499:303] 传入的变量RetainCount = 3 |
Objective-C中得ARC(Automatic Reference Counting)
1.ARC中应注意的问题:
(1). 不能显式调用dealloc语句, 或者实现或调用retain, release, retianCount 和 autorelease等方法。
(2).不能调用@selector (retain) ,@selector (release)等;
(3).不能使用NSAutoreleasePool对象, 用@autoreleasepool块来代替;
(4).不能用开头new的名称来定义一个属性,除非你定义一个别的getter名称。
2.ARC特性
ARC增加了新的属性定义关键字,strong来代替retain,表示强引用。用weak来代替assign表示弱引用。
作者:青玉伏案
出处:http://www.cnblogs.com/ludashi/
本文版权归作者和共博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如果文中有什么错误,欢迎指出。以免更多的人被误导。
收简历:坐标美团(北京总部),长期招聘FE/iOS/Android靠谱工程师,入职后,可内部联系楼主,有小礼品赠送,有意者可邮箱投递简历:zeluli@foxmail.com
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?