Objective C - ARC - 何时使用@autoreleasepool

2024-05-12

我读了一些关于 ARC 的文章,看到了这个:

@interface Address : NSObject {
    @public
    NSString *city;
}
@end

@implementation Address
- (Address*) init: (NSString*) c {
    city = c;

    return self;
}

- (void) dealloc {
    NSLog(@"Destroying address: %@", city);
}
@end

@interface Customer : NSObject {
    NSString *name;
    Address *addr;
}
@end

@implementation Customer
- (Customer*) init: (NSString*) n withAddress: (Address*) a {
    //Note 1: Automatic retain on assignment
    name = n;
    addr = a;

    return self;
}

- (void) dealloc {
    NSLog(@"Destroying: %@", name);
    //Note 2: Automatic release of member variables
}

@end

Customer* objectReturnTest() {
    NSString * n = [[NSString alloc] initWithString: @"Billy Bob"];
    Address * a = [[Address alloc] init: @"New York City"];      

    Customer *c = [[Customer alloc] init: n withAddress: a];

    //Note 3: ARC will put the returned object in autorelease pool.
    return c;
}

A couple of basic things to note here. As "Note 1"  says, when an object is assigned to a variable, a call to retain is made automatically. This increments the reference count. As "Note 2" says, when an object is destroyed, all member variable objects are released for you. You no longer have to do that from the dealloc method.

Finally, when a method returns a newly created object, ARC will put the returned object in an autorelease pool. This is stated in "Note 3".

Now, let’s use the code.

int main (int argc, const char * argv[])
{
    NSString * n = [[NSString alloc] initWithString: @"Johnny Walker"];
    Address * a = [[Address alloc] init: @"Miami"];
    Customer *c = [[Customer alloc] init: n withAddress: a];

    NSLog(@"Before force release");
    c = nil; //Force a release
    NSLog(@"After force release");

    @autoreleasepool {

        Customer *c2 = objectReturnTest();

    }
    NSLog(@"After autorelease pool block.");

    return 0;
}

The log output from this code will be:

Before force release

Destroying: Johnny Walker

After force release

Destroying: Billy Bob

Destroying address: New York City

After autorelease pool block.

Destroying address: Miami

A couple of things to note here. See how force release works. We set a variable to nil. ARC immediately releases the reference count. This causes the Customer object "Johnny Walker" to get destroyed. But, the member Address object "Miami" doesn’t get destroyed. This object gets destroyed at the very end of the main method. This is an extremely odd and non-intuitive behavior. Technically, this is not a memory leak, but, in reality member variables can pile up and take up a lot of memory. This is just as bad as memory leak.

The object return test works as expected. Customer "Billy Bob" is put in auto release pool. At the end of the @autoreleasepool block, the pool is drained and the object is released.

看这部分;

int main (int argc, const char * argv[])
{
    NSString * n = [[NSString alloc] initWithString: @"Johnny Walker"];
    Address * a = [[Address alloc] init: @"Miami"];
    Customer *c = [[Customer alloc] init: n withAddress: a];

    NSLog(@"Before force release");
    c = nil; //Force a release
    NSLog(@"After force release");

    @autoreleasepool {

        Customer *c2 = objectReturnTest();

    }
    NSLog(@"After autorelease pool block.");

    return 0;
}

当他这样做时 c = nil; c a 和 n 不应该全部被销毁吗?然而它说输出只是 n 被破坏了.. 有人可以解释为什么吗?

他说结果就像内存泄漏一样糟糕,那么你如何修复它呢?

最后一个问题,什么时候应该使用@autoreleaasepool?


by line

c = nil; //Forces a release

a Customer实例被释放,因为没有人保留它,因此输出是

摧毁:约翰尼·沃克

but n and a尚未被释放,因为它们仍然保留在范围内并且nil尚未分配给他们。

我不认为这是任何类型的内存泄漏


你通常不需要使用@autorelasepool,除非你正在做这样的事情

- (void)myMethod {
    for (int i = 0; i < 1000000; i++) {
        NSString *string = [NSString stringWithFormat:@"%d", i];
        // do something with string
    }
}

循环期间将分配超过 1000000 个 NSString。它们将在方法返回后(实际上是在此运行循环之后)被释放,但已经消耗了太多内存。因此应该替换为

- (void)myMethod {
    for (int i = 0; i < 1000000; i++) {
        @autoreleasepool {
            NSString *string = [NSString stringWithFormat:@"%d", i];
            // do something with string
        }
    }
}

您应该阅读本文以了解有关内存管理的更多信息https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Objective C - ARC - 何时使用@autoreleasepool 的相关文章

  • UITableViewCell的detailTextLabel滚动时消失

    我正在使用一个字符串数组 我在其中设置detailTextLabel从 最初所有字幕都设置正确 但如果我滚动detailTextLabel消失 UITableViewCell tableView UITableView tableView
  • 将 UIDatePicker 装入 UIActionSheet 中

    我正在尝试让带有 UIButton 的 UIDatePicker 显示在 UIActionSheet 中 不幸的是 它被剪掉了 整个日期选择器都不可见 我什至还没有尝试添加 UIButton 谁能建议让整个视图正确配合 我不确定如何添加正确
  • 如何使用苹果钥匙串?

    我正在尝试使用scifihifi iphone 来自 Github http github com ldandersen scifihifi iphone tree master security存储和检索用户名和密码 但是 当我添加课程时
  • 如何将 AFNetworking 2 与摘要式身份验证结合使用

    我一直在搜索 AFNetworking 2 with Digest Authentication 一段时间 但没有找到关于它的有用讨论 除了this one https github com AFNetworking AFNetworkin
  • 验证 iOS 应用程序时出现 com.apple.developer.linked-domains 问题

    当我在 Xcode 中使用 Organizer 验证我的项目时 出现以下错误 无效的代码签名权利 你的申请包的签名包含代码签名权利iOS 上不支持的 具体来说 值 for key com apple developer associated
  • cocos2d中获取CCSprite的绝对位置

    在我的游戏中 我有一个CCSprite绕另一个轨道运行CCSprite 很像电子绕原子核运行 我将电子作为原子核的子元素 以使动画更加简单 我所要做的就是旋转原子核 电子就会很好地跟随 然而 我的问题来自于想要让轨道动画看起来更时髦一点 通
  • Objective c,实例成员的内存管理

    我对实例成员的内存管理感到困惑 我有一个带有 ivar 的课程 DetailedResultsTableViewController detailedResultsTableViewController and property nonat
  • UIPageViewController:获取当前页面

    在过去的几天里 我一直在努力解决这个问题 经过所有这些杂耍 我发现我所需要的只是数据源方法中的当前索引 以使用当前可见页码进行更新 我有这个UIPageViewController数据源方法 我需要使用当前索引来获取委托方法的当前可见页面p
  • iOS 从另一个类更新 ViewController UILabel

    我是开发新手 一直在用头撞墙试图弄清楚这一点 我确信 我错过了一些愚蠢的东西 但在尝试了各种不同的解决方案后 我仍然无法得到结果我在寻找 我希望能够从另一个类更新 ViewController 中的 UILabel 这是一个我无法运行的小演
  • didReceiveRemoteNotification 未调用,iOS 10

    在 iOS 9 3 中 didReceiveRemoteNotification方法在以下两种情况下都会被调用 1 收到推送通知时 2 当用户通过点击通知启动应用程序时 但在 iOS 10 上 我注意到didReceiveRemoteNot
  • reloadData 调用 numberOfSections、numberOfRows,而不是 cellForRowAtIndexPath

    首先 如果格式不正确 我很抱歉 这是第一次这样做 我已经使用 stackoverflow 来寻求帮助很长时间了 它非常有帮助 谢谢大家 但这是我第一次发布自己的问题 这个问题已经被问过很多次了 但是当我调用 myTable reloadTa
  • NSString cString 已弃用。还有什么选择呢?

    我还有一个新手问题 我编写了一段代码 将 NSString 转换为 NSMutableData 以模拟 webService 结果 然而事实证明 cString 已被弃用 你能帮我更换它吗 这是我的代码 NSString testXMLDa
  • 我们可以在 Objective-C 中创建可空/非空属性吗?

    我们可以在 Objective C 中创建可空 非空属性吗 如果可以 那么如何创建 您可以使用 Nullable and Nonnull预选赛 property copy nullable NSString name property co
  • iOS 版 Google Analytics 中的线程崩溃

    使用适用于 iOS 版本 3 0 9 以及一般的 3 0 x 的 Google Analytics 库 我们看到很多像下面这样的崩溃 它们似乎是随机发生的 Exception Type SIGBUS Exception Codes BUS
  • Objective-C 2.0中的多线程问题

    我有我的主应用程序委托 其中包含一个返回对象的方法 该应用程序委托在主线程上运行 我还有一个在不同线程上运行的 NSOperation 除了希望有时能够在主线程上调用我的应用程序委托方法之外 我还需要从 NSOperation 线程中调用它
  • 如何使用 Restkit 0.20.0 创建/发布新的托管对象到服务器?

    我很难找到创建新托管对象 设置其值以及使用 Restkit 保存到服务器的文档或示例 我有一篇 NSManagedObject 帖子 interface Post NSManagedObject property nonatomic ret
  • 检测 SFSafariViewController 中的 URL 更改

    我有一个 SFSafariViewController 当用户点击我的应用程序中的链接时 它会打开 我需要检测 URL 何时更改 这样当它更改时 应用程序会显示警报 我们如何检测 SFSafariViewController 中的 URL
  • iOS 应用程序在被杀死之前平均在后台运行多长时间?

    我需要通过 API 检查后端的应用程序设置更新 因此我不确定在启动时执行此类检查是否足够 或者我需要在应用程序进入前台后立即执行此类检查 当然 这取决于打开的应用程序数量 设备功能 但是关于应用程序可以在后台存活多长时间直到被杀死 有什么一
  • 如何消除圆形矩形按钮周围的间隙而不删除其周围的边框? [复制]

    这个问题在这里已经有答案了 顺便提一句 这可能看起来像是关于按钮阴影问题的问题的重复 但它们有单调的背景 在我的例子中 背景是一些图像 所以简单的边框不能解决问题 While making app for iPhone Pad I noti
  • UIButton 图像调整大小/缩放以适合

    我有一个非常严重的问题 我不知道如何解决 我正在对 UIButtons 框架进行动画处理 当我对其进行动画处理时 我希望按钮中的图像缩放到与按钮相同的大小 它无需在我的 iPhone 模拟器上执行任何操作即可运行 但是当我在 iPad 模拟

随机推荐

  • Azure队列触发器函数未触发

    我用Python设计了一个Azure队列触发器函数 具有以下功能 当一条消息添加到名为 Input 的队列时 该函数会触发 它处理添加到输入队列的消息并将结果存储在输出队列中 现在我的问题是当我在本地运行时这工作正常 但是在部署函数应用程序
  • SDL Tridion 中的关键字路径

    有人可以提供一些关于如何做到这一点的想法吗 这可能非常简单和基础 但我无法弄清楚 这是我的要求 我有一个带有子关键字 B 的类别 A 而 B 有另一个子关键字 C 我想获取组件模板中所选关键字的确切路径 例如 如果用户选择关键字 C 我需要
  • saber sd 如何在没有 SPL 的情况下直接从 uboot 启动

    sabre sd 基于 imx 6 最大内部 RAM 约为 150Kb 然而 uboot 足够大 可以容纳在这个空间中 在这个场景中事情是如何进行的 https community freescale com docs DOC 95015
  • Coq:多个构造函数的单一表示法

    是否可以在 Coq 中为多个构造函数定义单一符号 如果构造函数的参数类型不同 则可以从中推断出它们 一个最小的 非 工作示例 Inductive A Set a b c C gt A d D gt A with C Set c1 c2 wi
  • ASP.Net MVC MvcBuildViews 大幅增加编译时间

    我们有一个项目 希望构建视图 以便在视图的 cshtml 文件中有任何错误时生成编译时错误 尽管如此 编译时间仍然急剧增加 MvcBuildViews true需要 62 秒 MvcBuildViews false需要 9 秒 这是可以接受
  • AVPlayerLooper 每次迭代后黑闪

    我正在使用 Apple 的示例代码在UICollectionViewCell背景 我在用着AVPlayerLooper 因为它是同一视频的迭代 我的问题是 当视频结束时 它会显示轻微的黑屏闪烁 也许它正在将视频搜索到0时间 我不确定 这是代
  • 为什么 Firefox 3.6 改变了 jQuery 和 CSS 属性?

    为什么 Firefox 3 6 改变了 jQuery 和 CSS 属性 好吧 更具体一点 我有一个交叉淡入淡出插件 可以在放置在彼此之上的两个图像之间创建发光效果 该函数 如下所示 将使顶部图像在悬停时在 200 毫秒内转换为不透明度 0
  • 使用成员作为实现者来实现接口

    我有实现 IA 的 A 类 现在我需要创建也应该实现 IA 的类 B B 类有 A 类的实例作为成员 有什么方法可以定义A的实例实现B类中的IA吗 interfase IA void method1 void method2 void me
  • 使用 svn diff 时如何获取无上下文

    当我从命令行使用 svn diff 时 它会打印出已更改的行 以及前后 3 个未更改的行以获取上下文 我更喜欢只看到没有上下文的更改行 我无法确定任何命令行选项可以让我让它以这种方式运行 默认情况下 标准 diff 和 cvs diff 执
  • 为什么奇数的切片容量与偶数的切片行为不同

    我注意到 当容量为奇数时 切片的容量会以不同的方式表现 更具体地说 当向切片添加元素时 切片的容量为doubled当原始容量为偶数时 但当原容量为奇数时 容量为增加一 然后加倍 例子 s make int 28 28 s append s
  • C 中“for”循环中的两个变量

    我正在编写一些代码 需要在其中使用两个变量for环形 下面的代码看起来没问题吗 它确实给了我预期的结果 for loop 1 offset loop 2 offset 2 loop 1 gt offset 190 loop 2 lt 190
  • 为什么 FB.Event.subscribe 会触发?

    是什么导致 FB Event subscribe 事件触发 我知道单击 fb login button 元素可以触发它 但只要创建 Facebook 会话 FB Event subscribe 事件就会触发 当存在 Facebook 会话时
  • MPMoviePlayerController 播放 YouTube 视频

    如何在 iPhone 上的 MPMoviePlayerController 中播放 YouTube 视频 同时避免进入全屏模式 这个问题已经在这里提出 MPMoviePlayerController 正在播放 YouTube 视频吗 htt
  • 从字符串中删除第一个和最后一个字符

    我有这个 dataList one two three list explode dataList echo pre print r list echo pre 其输出 gt Array gt 0 gt gt 1 gt one gt 2 g
  • 将具有多个时区的 pandas 列转换为单个时区

    Problem 我在 pandas DataFrame 中有一个列 其中包含带有时区的时间戳 此列中有两个不同的时区 我需要确保只有一个 这是该列末尾的输出 260003 2019 05 21 12 00 00 06 00 260004 2
  • 如何在没有 jQuery 或延迟加载的情况下推迟背景图像

    根据帕特里克 塞克斯顿tutorial https varvy com pagespeed defer images html 我想以与这里相同的方式推迟背景图像img img src data image png base64 R0lGO
  • 如何在 Java 中创建要打印到 JFrame 的 JLabels 数组

    我正在尝试制作一系列标签 每个标签都有一个来自函数的不同值 我不知道要使用的标签的确切数量 我的意思是可以打印任意数量的值 请帮我做这件事 很简单 只需一个方法返回一个数组或一些 JLabels 集合 并将它们全部添加到您的 JCompon
  • 更改弹出对话框的背景颜色

    我编写了显示弹出对话框的 android 代码 但我想将背景颜色从黑色更改为白色 然后更改文字颜色 这是对话框的代码 mPrefs PreferenceManager getDefaultSharedPreferences this Boo
  • 在 netBeans 中运行程序时,字体看起来非常奇怪

    我在我的新 MacBook M1 上设置了 netBeans 和 SceneBuilder 除了运行程序时的字体外 一切正常 它看起来像这样 我不知道为什么 按钮应显示 Click me 标签应显示 Hello 我收到的错误消息是 M rz
  • Objective C - ARC - 何时使用@autoreleasepool

    我读了一些关于 ARC 的文章 看到了这个 interface Address NSObject public NSString city end implementation Address Address init NSString c