连接 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 津津乐道对象的主要内容,如果未能解决你的问题,请参考以下文章