连接 C 与背景中的 ARC 津津乐道对象

Posted

技术标签:

【中文标题】连接 C 与背景中的 ARC 津津乐道对象【英文标题】:Connective C with ARC relishing objects in background 【发布时间】:2014-12-29 06:31:20 【问题描述】:

背景 我来自 C 背景,发现放弃手动内存管理非常痛苦。旧的目标 c 保留和发布模型虽然有点笨拙,但还可以。

我编写了一个 osX 应用程序,它从大小未知的未指定数据源读取数据,并对数据进行可视化呈现。为了给应用程序施加压力,我生成了一个非常大的数据集,该数据集在不到 3 分钟的时间内生成了超过一亿个对象(时间是一个猜测),但是当我删除包含具有亿个对象的可变数组的视图时,应用程序海滩球释放对象。我通过将数组传递给执行释放的后台线程解决了这个问题。无论如何,我不得不重新设计应用程序,以便它可以被沙盒化,我决定使用 ARC,现在我又回到了同样的压力测试,沙滩球又回来了。有没有办法让后台线程释放在 ARC 下创建的对象,或者我是否需要返回非 ARC 设计,如果我想用 Swift 重新编写应用程序怎么办。

问候克里斯蒂安·安徒生

【问题讨论】:

是否可以向您的代码显示对象是如何分配的? ARC 代码的行为与 MRC 代码不同,这没有根本原因 - 您只是将内存管理调用的手动插入替换为自动插入。检查您是否没有意外地在主线程中保留对大型数组的引用 - 在 MRC 下,当您在后台线程中释放时可能会导致悬空引用,可能会出现问题,但如果您不使用它则不会,但在ARC 这样的引用会阻止释放。 【参考方案1】:

有没有办法让后台线程释放在 ARC 下创建的对象

是的。只需将 nil 分配给后台线程上的变量。但是您应该确保该变量是唯一一个引用该值的变量。

#import <Foundation/Foundation.h>
#import <pthread.h>

pthread_t g_mainThread;

@interface Test : NSObject
@end

@implementation Test
- (void)dealloc

    NSLog(@"Test %p was dealloced on %s", self,
        g_mainThread == pthread_self() ? "the main queue" : "global queue");

@end

//主要

int main()

    g_mainThread = pthread_self();

    NSMutableArray *array = [[NSMutableArray alloc] init];
    for (int i = 0; i < 10; ++i) 
        Test *test = [[Test alloc] init];
        [array addObject:test];
    

    __block NSMutableArray *arrayOnGlobalQueue = array;

    /*
     * The array object was referenced from *array* and *arrayOnGlobalQueue* variables.
     * The reference count of the array object is 2.
     */

    array = nil;

    /*
     * The *array* variable doesn't refer the array object any more.
     * The reference count of the array object is 1.
     */

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    dispatch_async(queue, ^

        /*
         * Assign nil to the variable for releasing the array object
         */

        arrayOnGlobalQueue = nil;

        /*
         * The *arrayOnGlobalQueue* variable doesn't refer the array object any more.
         * The reference count of the array object is 0.
         * Thus the array object was dealloced on the background thread(queue).
         */

    );

    dispatch_main();

    return 0;

结果是这样的。

Test 0x7f96aac033b0 was dealloced on global queue
...

但是,一般情况下,AutoreleasePool引用对象,AutoreleasePool在主线程释放对象。

例如,如果你使用 NSMutableArray +array 类方法来实例化数组对象而不是 +alloc 和 -init 方法,

NSMutableArray *array = [NSMutableArray array];
// NSMutableArray *array = [[NSMutableArray alloc] init];

表示数组对象注册到自动释放池。因此,数组对象的引用计数为 2。使用@autoreleasepool 可以避免这种情况。

我是否需要返回非 ARC 设计

在非 ARC 下使用 release 而不是将 null 分配给 ARC 下的变量。

如果我想用 Swift 重新编写应用程序怎么办

与 Objective-C 完全一样。

【讨论】:

感谢它正是我正在寻找的解决方案,我有点接近那个解决方案,但它还没有工作。我正在使用 +alloc -init 你是说我更适合使用 +array 吗? 真正起作用的唯一问题是,如果我通过数组说我的应用程序控制器释放数据,那么在后台执行完成之前,显示数据的对象不会消失。我想在后台线程中发布数据的原因是我可以清理 UI 并继续下一个演示文稿,而不必等待 180 亿个对象发布任何建议 我看到的最后一条消息是 CoreAnimation: warning, deleted thread with uncommitted CATransaction;在环境中设置 CA_DEBUG_TRANSACTIONS=1 以记录回溯。我会做明显的回溯,但我认为我需要将数组传递给一个我不会去皮的对象 等等,你想在后台线程上释放 UIView 对象吗? UIKit 不是线程安全的,所以不可能。 不不,它们不是 UIView,而是 NSMutableArrays 中的 NSMutableArray 中的 NSStrings

以上是关于连接 C 与背景中的 ARC 津津乐道对象的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder ARC 076E - Connected?

arc音频回传功能需要投影支持吗

ARC 会在啥条件下保留该对象?

左外连接与同一个表作为外连接的一部分

c与数据库连接的详细步骤

关于家庭影院以及HDMI ARC功能使用方法