连接C与ARC在背景中欣赏对象

时间:2014-12-29 06:31:21

标签: objective-c automatic-ref-counting release

背景 我来自C背景,并发现放弃手动内存管理非常痛苦。旧的目标c保留和释放模型是好的,如果不是有点笨拙。

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

关心Christian Andersen

1 个答案:

答案 0 :(得分:0)

  

有没有办法让后台线程来释放在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

// main

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
...

但是,在常见情况下,Autorelease Pool引用对象,Autorelease Pool释放主线程上的对象。

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

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

这意味着数组对象已注册到Autorelease Pool。因此,数组对象的引用计数为2.您可以使用@autoreleasepool避免这种情况。

  

我是否需要返回非ARC设计

在非ARC下使用release,而不是在ARC下为变量指定null。

  

如果我想在Swift中重新编写应用程序

,该怎么办?

与Objective-C完全相同。