iPhone内存管理详细解说(二)
继上一篇之后,再来讲述iPhone内存管理的细节.
四:动态内存管理
第四节就内容实质来说跟第三节的object的拥有和丢弃政策是一样的,不过是从以代码为引导的动态形式讲述.所以你会在这一节看到许多代码例子帮助你理解.核心还是那些基本的规则.
1.基本知识
主要规则还是object所有权,文档在这里重复性太大,我就只写一些值得注意的地方. 我们会看到很多类提供以”+className…”这种形式的代码(下面有例子),这在文档中叫做”convenience constructors”,记住你用这种方法返回而来的object你是没有所有权的,所以没有责任去释放.
2.一些简单的例子
以下三个例子较为简单地介绍用alloc或convenience constructor或accessor method得到object的区别,看代码:
- (void)printHello {NSString *string;string = [[NSString alloc] initWithString:@"Hello"];NSLog(string);[string release];
}
你用alloc得到的string,有义务用release释放.
- (void)printHello {NSString *string;string = [NSString stringWithFormat:@"Hello"];NSLog(string);
}
你用convenience constructor得到的string,放心地不用再管它了.
- (void)printWindowTitle {NSString *string;string = [myWindow title];NSLog(string);
}
你用accessor method得到的string,跟convenience constructor一样,放心地不用再管它了.
3.使用Accessor Methods
官方文档的建议是:相对于频繁的使用retain和release,更好的做法是使用accessor methods.比如我有这么一个object,它的类声明是:
@interface Counter : NSObject {NSNumber *count;
}
为了get和set这个count,你要定义两个accessor methods(下面的例子较为简单,详细的accessor methods在后面几节会讲述).get是:
- (NSNumber *)count {return count;
}
set稍微复杂点:
- (void)setCount:(NSNumber *)newCount {[newCount retain];[count release];// make the new assignmentcount = newCount;
}
因为你要防止newCount被别人释放了,所以你需要有拥有权,同时把之前你占有所有权的那个count释放掉.
上面提到推荐使用accessor methods,不过在init方法和dealloc里则例外,比如在init里你需要这么写:
- init {self = [super init];if (self) {count = [[NSNumber alloc] initWithInteger:0];}return self;
}
如果想灵活一点使其可以自己设定值,可以:
- initWithCount:(NSNumber *)startingCount {self = [super init];if (self) {count = [startingCount copy];}return self;
}
而在dealloc里,则需要释放count:
- (void)dealloc {[count release];[super dealloc];
}
实现一个reset重置方法: 你可以有两种方法:
(1)使用convenience constructor,很省心地不用再考虑何时释放:
- (void)reset {NSNumber *zero = [NSNumber numberWithInteger:0];[self setCount:zero];
}
(2)使用传统的alloc,需要释放:
- (void)reset {NSNumber *zero = [[NSNumber alloc] initWithInteger:0];[self setCount:zero];[zero release];
}
常见错误 (1)不使用accessor methods,那么你经常会忘记retain或release而犯错,如:
- (void)reset {NSNumber *zero = [[NSNumber alloc] initWithInteger:0];[count release];count = zero;
}
(2)实例内存泄漏,如:
- (void)reset {NSNumber *zero = [[NSNumber alloc] initWithInteger:0];[self setCount:zero];
}
忘记release后,这个zero你再也release不掉了.
(3)release没有所有权的实例,如:
- (void)reset {NSNumber *zero = [NSNumber numberWithInteger:0];[self setCount:zero];[zero release];
}
4.经常引起困惑的情形
(1)使用集合类(如array, dictionary, 或 set)
当添加一个object给集合类的实例时,这个集合类的实例拥有所有权,当这个object从集合类的实例中移除时,或集合类的实例自身被release了,就会释放这个object的所有权.例如创建一个数的array,你可以:
NSMutableArray *array;
NSUInteger i;
// ...
for (i = 0; i < 10; i++) {NSNumber *convenienceNumber = [NSNumber numberWithInteger:i];[array addObject:convenienceNumber];
}
没必要retain,array就有所有权.当然你也可以:
NSMutableArray *array;
NSUInteger i;
// ...
for (i = 0; i < 10; i++) {NSNumber *allocedNumber = [[NSNumber alloc] initWithInteger: i];[array addObject:allocedNumber];[allocedNumber release];
}
(2)从方法中返回objects
这个很简单了,跟第三节也有重复,直接给出四个情形,你先自己判断一下吧:
- (NSString *)fullName {NSString *string = [NSString stringWithFormat:@"%@ %@", firstName, lastName];return string;
}- (NSString *)fullName {NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName] autorelease];return string;
}- (NSString *)fullName {NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName] release];return string;
}- (NSString *)fullName {NSString *string = [[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName];return string;
}
很明显吧,前两个是对的,后两个是扯淡的.若对这个还有疑问,直接回复提问吧.
iPhone内存管理详细解说(二)相关推荐
- iPhone内存管理详细解说(一)
iPhone内存管理详细解说系列转载来源:http://keywind.me/blog/2011/05/07/iphonenei-cun-guan-li-xiang-xi-jie-shuo-yi/ 感 ...
- C语言内存管理内幕(二)----半自动内存管理策略
2019独角兽企业重金招聘Python工程师标准>>> C语言内存管理内幕(二)----半自动内存管理策略 转载于:https://my.oschina.net/hengcai001 ...
- 内存管理(二) ARC
内存管理(二) ARC 上篇我们介绍了MRC,本篇我们介绍下ARC ARC概述 ARC是一种编译器功能,它通过LLVM编译器和Runtime协作来进行自动管理内存.LLVM编译器会在编译时在合适的地方 ...
- Linux内存管理(二)
Linux内存管理之二:Linux在X86上的虚拟内存管理 本文档来自网络,并稍有改动. 前言 Linux支持很多硬件运行平台,常用的有:Intel X86,Alpha,Sparc等.对于不能够通用的 ...
- 同样学习Linux, 为何差别这么大? - 论打通Linux进程和内存管理任督二脉
穆赫兰道和内陆帝国 我在多年的工程生涯中发现很多工程师碰到一个共性的问题:Linux工程师很多,甚至有很多有多年工作经验,但是对一些关键概念的理解非常模糊,比如不理解CPU.内存资源等的真正分布,具体 ...
- iphone内存管理
http://hi.baidu.com/spopavenvldiqyr/item/c8d620b6282c4d4abb0e122a iphone内存管理(一) BY 洋葱头 http://hi.bai ...
- iphone内存管理(二)
(2)尽量避免使用autorelease 虽然autorelease非常简单有用,但是在iphone上一定要谨慎使用,毕竟iphone内存相当有限.autorelease可能会导致直接的隐型内存泄露. ...
- iPad/iPhone内存管理四之viewDidUnload/dealloc详细解说
在进行内存管理时,我们必须要知道这两者的区别时什么. viewDidUnload是在程序接到内存警告的时候调用的,在这时候,我们可以把我们不需要的东西去掉或者让他等于nil. dealloc是在计数等 ...
- FreeRTOS--堆内存管理(二)
堆内存管理代码具体实现 heap_1 内存申请函数 内存释放函数 heap_2 内存块 内存堆初始化函数 内存块插入函数 内存申请函数 判断是不是第一次申请内存 开始分配内存 内存释放函数 heap_ ...
最新文章
- 企业为什么要开通银企直联_企业为什么要把人事外包出去
- 卷进大厂系列之LeetCode刷题笔记:设计链表(中等)
- 【错误记录】Ubuntu 中 ROOT 用户无法启动 Visual Studio Code 开发环境 ( 推荐在普通用户下使用 VSCode 开发环境 )
- switch手柄可以连电脑吗_电脑可以拍照吗
- 检查本地服务器是否配置成功
- ASP.NET 安全认证(三)—— 用Form 表单认证实现单点登录(Single Sign On) .
- 数据库-优化-groupby的优化
- hook什么意思_这是什么骚代码!
- python中返回值为ture表达式_python return逻辑判断表达式(21)|python教程|python入门|python教程...
- Python技术知识清单(数据分析)
- 投简历:求求你给我个机会「小废物招聘全记录①」
- 在线班课程-第10周 http基础知识、nginx网站服务
- 人工智能 —— 语义网络推理
- 惠普LaserJet M1005 MFP报错b2
- 高配云计算机平台,云电脑真的来了!小破本也能秒变高配
- 《悲情曹雪芹》——诗篇总结
- 如何用网页脚本追踪用户
- 关于程序猿 59 条搞笑但却真实无比的语录
- metaq spring
- 理财系列 3 股票体检指标之市净率