继上一篇之后,再来讲述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内存管理详细解说(二)相关推荐

  1. iPhone内存管理详细解说(一)

    iPhone内存管理详细解说系列转载来源:http://keywind.me/blog/2011/05/07/iphonenei-cun-guan-li-xiang-xi-jie-shuo-yi/ 感 ...

  2. C语言内存管理内幕(二)----半自动内存管理策略

    2019独角兽企业重金招聘Python工程师标准>>> C语言内存管理内幕(二)----半自动内存管理策略 转载于:https://my.oschina.net/hengcai001 ...

  3. 内存管理(二) ARC

    内存管理(二) ARC 上篇我们介绍了MRC,本篇我们介绍下ARC ARC概述 ARC是一种编译器功能,它通过LLVM编译器和Runtime协作来进行自动管理内存.LLVM编译器会在编译时在合适的地方 ...

  4. Linux内存管理(二)

    Linux内存管理之二:Linux在X86上的虚拟内存管理 本文档来自网络,并稍有改动. 前言 Linux支持很多硬件运行平台,常用的有:Intel X86,Alpha,Sparc等.对于不能够通用的 ...

  5. 同样学习Linux, 为何差别这么大? - 论打通Linux进程和内存管理任督二脉

    穆赫兰道和内陆帝国 我在多年的工程生涯中发现很多工程师碰到一个共性的问题:Linux工程师很多,甚至有很多有多年工作经验,但是对一些关键概念的理解非常模糊,比如不理解CPU.内存资源等的真正分布,具体 ...

  6. iphone内存管理

    http://hi.baidu.com/spopavenvldiqyr/item/c8d620b6282c4d4abb0e122a iphone内存管理(一) BY 洋葱头 http://hi.bai ...

  7. iphone内存管理(二)

    (2)尽量避免使用autorelease 虽然autorelease非常简单有用,但是在iphone上一定要谨慎使用,毕竟iphone内存相当有限.autorelease可能会导致直接的隐型内存泄露. ...

  8. iPad/iPhone内存管理四之viewDidUnload/dealloc详细解说

    在进行内存管理时,我们必须要知道这两者的区别时什么. viewDidUnload是在程序接到内存警告的时候调用的,在这时候,我们可以把我们不需要的东西去掉或者让他等于nil. dealloc是在计数等 ...

  9. FreeRTOS--堆内存管理(二)

    堆内存管理代码具体实现 heap_1 内存申请函数 内存释放函数 heap_2 内存块 内存堆初始化函数 内存块插入函数 内存申请函数 判断是不是第一次申请内存 开始分配内存 内存释放函数 heap_ ...

最新文章

  1. 企业为什么要开通银企直联_企业为什么要把人事外包出去
  2. 卷进大厂系列之LeetCode刷题笔记:设计链表(中等)
  3. 【错误记录】Ubuntu 中 ROOT 用户无法启动 Visual Studio Code 开发环境 ( 推荐在普通用户下使用 VSCode 开发环境 )
  4. switch手柄可以连电脑吗_电脑可以拍照吗
  5. 检查本地服务器是否配置成功
  6. ASP.NET 安全认证(三)—— 用Form 表单认证实现单点登录(Single Sign On) .
  7. 数据库-优化-groupby的优化
  8. hook什么意思_这是什么骚代码!
  9. python中返回值为ture表达式_python return逻辑判断表达式(21)|python教程|python入门|python教程...
  10. Python技术知识清单(数据分析)
  11. 投简历:求求你给我个机会「小废物招聘全记录①」
  12. 在线班课程-第10周 http基础知识、nginx网站服务
  13. 人工智能 —— 语义网络推理
  14. 惠普LaserJet M1005 MFP报错b2
  15. 高配云计算机平台,云电脑真的来了!小破本也能秒变高配
  16. 《悲情曹雪芹》——诗篇总结
  17. 如何用网页脚本追踪用户
  18. 关于程序猿 59 条搞笑但却真实无比的语录
  19. metaq spring
  20. 理财系列 3 股票体检指标之市净率

热门文章

  1. 四百左右的蓝牙耳机有哪些?四百左右好用的蓝牙耳机推荐
  2. 1404111-67-6,N-Boc-PEG5-alcohol,N-Boc-PEG5-CH2CH2OH实验室常用试剂的保存方法
  3. 2022山东国际青少年眼睛健康产业展览会,护眼健康展9月开展
  4. 微信商户号 API 密钥、API 证书配置
  5. 2022渗透测试-信息收集笔记
  6. 买了智能电视之后还需要购买搭配机顶盒吗?
  7. 消防中计算机基础知识,消防基础知识考试题
  8. 在虚拟机上调试网络时要注意的内容
  9. 牛与马的把表情包(带有改进)
  10. 本地网络环境测试工具,很不错的工具