博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
高级内存管理编程指南-内存管理政策
阅读量:3590 次
发布时间:2019-05-20

本文共 2884 字,大约阅读时间需要 9 分钟。

内存管理政策

用于参考计数环境中的内存管理的基本模型由   协议中定义的方法和标准方法命名约定的组合提供。的NSObject类也定义了一种方法,dealloc即自动当对象被释放调用。本文介绍了在 Cocoa 程序中正确管理内存所需了解的所有基本规则,并提供了一些正确用法的示例。

基本内存管理规则

内存管理模型基于对象所有权。任何对象都可能拥有一个或多个所有者。只要一个对象至少有一个所有者,它就会继续存在。如果对象没有所有者,则运行时系统会自动销毁它。为了确保在拥有对象时它是清楚的,当你没有时,Cocoa 设置以下策略:

  • 您拥有自己创建的任何对象

    您创建使用名称以 “黄金” 的方法的对象,“新”,“复制”,或 “mutableCopy”(例如 或 )。

  • 您可以使用 retain 获取对象的所有权

    通常保证接收到的对象在接收到的方法中保持有效,并且该方法也可以安全地将对象返回给其调用者。您可以retain在两种情况下使用:(1)访问在器方法或init方法的实现中,获取要作为属性值存储的对象的所有权;(2)防止对象因某些其他操作的副作用而失效(如)。

  • 当您不再需要它时,您必须放弃您拥有的对象的所有权

    您通过向对象发送 消息或 消息来放弃对象的所有权。因此,在 Cocoa 术语中,放弃对象的所有权通常被称为 “释放” 对象。

  • 您不得放弃您不拥有的对象的所有权

    这只是先前明确规定的政策规则的必然结果。

一个简单的例子

要说明策略,请考虑以下代码片段:

{
Person * aPerson = [[Person alloc] init];
// ...
NSString * name = aPerson.fullName;
// ...
[aPerson发布];
}

人对象是使用该alloc方法创建的,因此随后release在不再需要时发送消息。不使用任何拥有方法检索此人的姓名,因此不会发送release消息。但请注意,该示例使用的是release而不是autorelease

使用 autorelease 发送延期版本

autorelease需要发送延迟release消息时使用 - 通常在从方法返回对象时使用。例如,您可以实现如下fullName方法:

- (NSString *)fullName {
NSString * string = [[[NSString alloc] initWithFormat:@“%@%@”,
self.firstName,self.lastName] autorelease];
返回字符串;
}

你拥有返回的字符串alloc。要遵守内存管理规则,您必须在丢失对该字符串的引用之前放弃该字符串的所有权。release但是,如果使用,则在返回字符串之前将解除分配该字符串(并且该方法将返回无效对象)。使用autorelease,表示您想放弃所有权,但允许方法的调用者在释放之前使用返回的字符串。

也。你可以实现这样的fullName方法:

- (NSString *)fullName {
NSString * string = [NSString stringWithFormat:@“%@%@”,
self.firstName,self.lastName];
返回字符串;
}

遵循基本规则,您不拥有返回的字符串stringWithFormat:,因此您可以安全地从方法返回字符串。

相比之下,以下实现是错误的

- (NSString *)fullName {
NSString * string = [[NSString alloc] initWithFormat:@“%@%@”,
self.firstName,self.lastName];
返回字符串;
}

根据命名约定,任何没有东西可以表示fullName方法的调用者拥有报道查看的字符串。因此调用者没有理由释放返回的字符串,因此它将被泄露。

您不拥有通过引用返回的对象

Cocoa 中的一些方法指定通过引用返回一个对象(也就是说,它们采用类型的参数ClassName **id *)。常见的模式是使用NSError包含错误信息的对象(如果出现错误),如 NSData)和 NSString)所示。

在这些情况下,适用的规则与已经描述的相同。当您调用这些方法中的任何一个时,不会都创建 ³³ 该NSError对象,因此不您拥有该对象。因此无需释放它,如下例所示:

NSString * fileName = <#获取文件名#>;
NSError *错误;
NSString * string = [[NSString alloc] initWithContentsOfFile:fileName
encoding:NSUTF8StringEncoding error:&error];
if(string == nil){
//处理错误......
}
// ...
[string release];

实施 dealloc 以放弃对象的所有权

NSObject类定义的方法,即自动调用当一个对象不具有拥有者和它的存储器被回收 - 可可术语它是 “释放” 或 “释放”.. 该dealloc方法的作用是释放对象自己的内存,并处置它拥有的任何资源,包括任何对象实例变量的所有权。

以下示例说明了如何dealloc为人类实现方法:

@interface Person:NSObject
@property(retain)NSString * firstName;
@property(retain)NSString * lastName;
@property(assign,readonly)NSString * fullName;
@结束
 
@implementation人
// ...
- (无效)dealloc
[_firstName release];
[_lastName release];
[super dealloc];
}
@结束

重要说明:  永远不要dealloc直接调用另一个对象的方法。

必须您在实现结束时调用超类的实现。

您不应该将系统资源的管理与对象生命周期联系起来;请参阅。

当应用程序终止时,不会可能向对象发送dealloc消息。因为进程的内存在退出时自动清除,所以仅仅允许操作系统清理资源比调用所有内存管理方法更有效。

 

核心基金会使用相似但不同的规则

Core Foundation 对象有类似的内存管理规则(请参阅 Core Foundation 的)。但是,Cocoa 和 Core Foundation 的命名约定是不同的。特别是,Core Foundation 的创建规则(请参阅)不适用于返回 Objective-C 对象的方法。例如,在以下代码片段中,您负责放弃以下所有权myInstance

MyClass * myInstance = [MyClass createInstance];

转载地址:http://lqhwn.baihongyu.com/

你可能感兴趣的文章
TortoiseSVN无法查看日志
查看>>
centos7设置svn开机自启
查看>>
nginx负载均衡配置
查看>>
idea将普通java代码打成jar包
查看>>
java快速读取大数据量的Excel文件,格式为.xlsx
查看>>
将普通maven工程中某一接口改造成dubbo服务
查看>>
k8s集群中其他节点也可以执行kubectl命令
查看>>
使用docker制作tomcat镜像
查看>>
shell脚本读取文件内容,并写出新文件
查看>>
在docker宿主机上运行docker中container中的执行的命令
查看>>
nginx和tomcat的ssl认证使用https协议访问
查看>>
docker使用tomcat部署应用
查看>>
linux服务器之间复制文件
查看>>
k8s集群搭建
查看>>
自己的阿里云镜像加速器查找
查看>>
spring-cloud-eureka初体验
查看>>
spring-cloud-ribbon简单使用
查看>>
spring-cloud-feign的简单使用
查看>>
spring-cloud-hystrix简单使用
查看>>
docker批量删除镜像
查看>>