iOS使用自动释放池

news/2024/7/20 20:04:18 标签: ios, cocoa, java

文章目录

  • 使用自动释放池
    • 关于自动释放池
    • 使用本地自动释放池块来减少峰值内存占用空间
    • 自动释放池块和线程

实用内存管理

使用自动释放池

自动释放池块提供了一种机制,您可以放弃对对象的持有,但避免立即将其释放的可能性(例如,当您从方法返回对象时)。通常,不需要创建自己的自动释放池块,但在某些情况下,必须这样做,或者这样做是有益的。

关于自动释放池

使用@autoreleasepool标记自动释放池块,如以下示例所示:

@autoreleasepool {
    // Code that creates autoreleased objects.
}

在自动释放池块的末尾,在块内收到自动释放消息的对象将被发送release消息——对象每次在块内发送autorelease消息时都会收到release消息。
像任何其他代码块一样,自动释放池块可以嵌套:

@autoreleasepool {
    // . . .
    @autoreleasepool {
        // . . .
    }
    . . .
}

(您通常不会完全看到上述代码;通常,一个源文件中的自动发布池块中的代码会调用另一个自动发布池块中包含的另一个源文件中的代码。)对于给定的autorelease消息,相应的release消息在发送autorelease消息的自动发布池块的末尾发送。

Cocoa总是希望代码在自动释放池块内执行,否则自动释放的对象不会被释放,应用程序会泄漏内存。(如果您在自动释放池块之外发送自动释放消息,Cocoa会记录一个合适的错误消息。)AppKit和UIKit框架在自动释放池块中处理每个事件循环迭代(例如鼠标向下事件或点击)。因此,您通常不必自己创建自动释放池块,甚至不必查看用于创建池块的代码。然而,有三种情况下,您可能会使用自己的自动释放池块:

  • 如果您正在编写一个不基于UI框架的程序,例如命令行工具。

  • 如果你写一个创建许多临时对象的循环。

您可以在循环中使用自动释放池块在下一次迭代之前处理这些对象。在循环中使用自动释放池块有助于减少应用程序的最大内存占用。

  • 如果您生成了一个次要线程。

您必须在线程开始执行时立即创建自己的自动释放池块;否则,您的应用程序将泄露对象。(有关详细信息,请参阅自动释放池块和线程。)

使用本地自动释放池块来减少峰值内存占用空间

许多程序会创建自动释放的临时对象。这些对象直到块结束会增加程序的内存占用。在许多情况下,允许临时对象累积到当前事件循环迭代结束不会导致过多的开销;但是,在某些情况下,您可能会创建大量临时对象,这些对象会大幅增加内存占用空间,并且您希望更快地处理这些对象。在后一种情况下,您可以创建自己的自动释放池块。在块的末尾,临时对象被释放,这通常会导致它们dealloc,从而减少程序的内存占用。

以下示例展示了如何在for循环中使用本地自动发布池块。

NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls) {
 
    @autoreleasepool {
        NSError *error;
        NSString *fileContents = [NSString stringWithContentsOfURL:url
                                         encoding:NSUTF8StringEncoding error:&error];
        /* Process the string, creating and autoreleasing more objects. */
    }
}

For循环一次处理一个文件。在自动释放池块内发送自动释放消息的任何对象(如文件内容)都会在块末尾释放。

在自动释放池块之后,您应该将块内自动释放的任何对象视为“已禁用”。不要向该对象发送消息或将其返回给方法的调用者。如果您必须在自动释放池块之外使用临时对象,您可以通过向块内的对象发送retain消息,然后在块后发送自动释放,如本示例所示:

(id)findMatchingObject:(id)anObject {
 
    id match;
    while (match == nil) {
        @autoreleasepool {
 
            /* Do a search that creates a lot of temporary objects. */
            match = [self expensiveSearchForObject:anObject];
 
            if (match != nil) {
                [match retain]; /* Keep match around. */
            }
        }
    }
 
    return [match autorelease];   /* Let match go and return it. */
}

在自动释放池块内向match发送retain消息,并在自动释放池块延长match寿命后向其发送自动释放,并允许它在循环之外接收消息并返回给findMatchingObject的调用者:

自动释放池块和线程

Cocoa应用程序中的每个线程都维护自己的自动释放池块堆栈。如果您正在编写仅限基础的程序,或者如果您分离线程,则需要创建自己的自动发布池块。

如果您的应用程序或线程寿命长,并可能生成大量自动释放对象,您应该使用自动释放池块(如AppKit和UIKit在主线程上所做的那样);否则,自动释放对象会累积,您的内存占用也会增加。如果您的分离线程不进行Cocoa调用,则无需使用自动释放池块。

注意:如果您使用POSIX线程API而不是NSThread创建辅助线程,除非Cocoa处于多线程模式,否则无法使用Cocoa。Cocoa只有在分离其第一个NSThread对象后才能进入多线程模式。要在次要POSIX线程上使用Cocoa,您的应用程序必须首先至少分离一个NSThread对象,该对象可以立即退出。您可以使用NSThread类方法isMultiThreaded测试Cocoa是否处于多线程模式。


http://www.niftyadmin.cn/n/254639.html

相关文章

解决修改docker源无用的问题

docker原来的源很慢&#xff0c;想要修改成国内比较快的源&#xff0c;但是我在页面上操作完成、重启后&#xff0c;并没有生效 docker pull opengauss/opengauss:3.1.0 3.1.0: Pulling from opengauss/opengauss Get "https://registry-1.docker.io/v2/": dialing…

【AI绘画】Midjourney的使用及程序示例

Midjourney 1.背景2.Midjourney的原理3.Midjourney的使用方法4.Midjourney的示例代码 1.背景 Midjourney 是一款基于深度学习的图像转换工具&#xff0c;其可以将一张图像转换成具有不同风格的图像&#xff0c;例如将一张照片转换成卡通风格的图像。Midjourney 基于 TensorFlow…

docker容器:Docker-Compose

目录 一、Docker-Compose 1、Docker-Compose使用场景 2、Docker-Compose简介 3、Docker-Compose安装部署 4、YML文件编写注意事项 5、Compose配置常用字段 6、 Docker Compose 常用命令 7、Docker Compose 文件结构 8、docker Compose撰写nginx 镜像 9、docker Compos…

数字化转型框架如何搭建?

根据GetSmarter对来自128个国家/地区的5808名专业人士进行关于数字化转型的调查&#xff0c;揭示了几个重要的发现。 首先是所有行业和工作角色对数字化转型的看法不同。它不仅仅专注于集成和利用新技术&#xff0c;例如机器学习(ML)、人工智能(AI)、大数据和自动化。它是关于…

Java常见开发工具和Object类

Java是一种面向对象的编程语言&#xff0c;被广泛应用于各种应用程序和软件开发中。在Java开发过程中&#xff0c;使用一个好的开发工具可以大大提高开发效率和代码质量。Eclipse是一个功能强大、灵活易用的Java集成开发环境&#xff08;IDE&#xff09;&#xff0c;被广泛使用…

JVM调优最佳参数

项目背景 C端的项目&#xff0c;用户量比较多&#xff0c;请求比较多。 启动参数表 Xmx指定应用程序可用的最大堆大小。 Xms指定应用程序可用的最小堆大小。 &#xff08;一般情况下&#xff0c;需要设置Xmx和Xms为相等的值&#xff0c;且为一个固定的值&#xff09; 如果该值…

移动端导航设计

根据产品层级的深度和广度&#xff0c;选择适合的导航模式&#xff0c;是产品设计中的关键一环。 任何APP的组织信息都需要以某种导航框架固定起来&#xff0c;一个新的产品合适的导航框架&#xff0c;决定了产品之后的延伸和扩展。 移动端的屏幕尺寸就这么大&#xff0c;操作方…

go1.20环境安装以及beego框架配置

打开网址下载安装包选择对应安装包来下载安装(个人是windows&#xff0c;下载的1.20.3版本) 默认情况下会安装在C盘&#xff0c;但是我安装在了D盘目录 根据安装提示一步步next&#xff0c;直至完成 go get 在1.18版本之后就弃掉了&#xff0c;换成了install 配置自己的work…