【问题标题】:xcode ios ARC (automatic reference counting) regarding dispatch_async and nsdataxcode ios ARC(自动引用计数)关于 dispatch_async 和 nsdata
【发布时间】:2012-11-19 17:00:24
【问题描述】:

我有一个关于 xcode ARC 的初学者问题。以下代码没有内存问题,因为内存已被 ARC 释放。

- (void)viewDidLoad
{
    [super viewDidLoad];    
    // test nsmutabledata
    dispatch_queue_t testQueue = dispatch_queue_create("testQueue", NULL);
    dispatch_async(testQueue, ^{
        while (1) {
            NSMutableData *testData = [[NSMutableData alloc]initWithCapacity:1024*1024*5];
            NSLog(@"testData size: %d", testData.length);
        }
    });
}

但是,下面没有,几秒钟后给我内存分配错误。

+ (NSMutableData *) testDataMethod
{
    NSMutableData *testDataLocal =  [[NSMutableData alloc]initWithCapacity:1024*1024*5];
    return testDataLocal;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // test nsmutabledata
    dispatch_queue_t testQueue = dispatch_queue_create("testQueue", NULL);
    dispatch_async(testQueue, ^{
        while (1) {
            NSMutableData *testData = [RootViewController testDataMethod];
            NSLog(@"testData size: %d", testData.length);
        }
    });
}

我对 ARC 有错误的理解吗?我虽然 testDataLocal 被计算一次,但在方法退出时超出了范围。 testData 是另一个计数,但在循环的下一次迭代中 testData 应该没有计数,并被系统释放。

【问题讨论】:

    标签: objective-c ios memory-management automatic-ref-counting grand-central-dispatch


    【解决方案1】:

    在第一段代码中,NSMutableData 对象在每次循环迭代结束时被释放,以避免任何内存问题。

    在第二段代码中,testDataMethod 的返回值很可能是自动释放的。由于您的应用程序在一个紧密的循环中运行,因此自动释放池从未有机会被刷新,因此您很快就会耗尽内存。

    尝试将您的第二段代码更改为:

    while (1) {
        @autoreleasepool {
            NSMutableData *testData = [RootViewController testDataMethod];
            NSLog(@"testData size: %d", testData.length);
        }
    }
    

    【讨论】:

    • 谢谢,这似乎确实有效。当我需要将紧密循环分派到另一个线程时,这是标准做法吗?
    • 使用@autoreleasepool 是很常见的(并且基本上是必需的)在您处于可能创建大量自动释放对象的循环中的情况下。这与调度队列无关。这是一个基本的内存管理问题。具有大量自动释放对象的长时间运行循环始终需要使用自动释放池。无论有没有 ARC,这都是正确的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多