背景 我来自C背景,并发现放弃手动内存管理非常痛苦。旧的目标c保留和释放模型是好的,如果不是有点笨拙。
我编写了一个osX应用程序,它从未指定大小的未指定数据源中读取数据,并对数据进行可视化表示。为了给应用程序施加压力,我生成了一个非常大的数据集,在不到3分钟的时间内生成了超过一亿个对象(时间是一个猜测)但是当我去掉包含可变数组的视图时,有数亿个对象的应用程序海滩咆哮而解除分配对象。我通过将数组传递给执行发布的后台线程解决了这个问题。无论如何,我不得不重新设计应用程序,所以它可以沙盒,我决定使用ARC,现在我回到相同的压力测试,海滩球回来了。有没有办法让我可以获得后台线程来发布在ARC下创建的对象,或者我是否需要返回非ARC设计,如果我想在Swift中重新编写应用程序,该怎么办。
关心Christian Andersen
答案 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完全相同。