1

我有一個關於xcode ARC的初學者問題。下面的代碼沒有內存問題,因爲內存由ARC釋放。xcode ios關於dispatch_async和nsdata的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應該沒有計數,並且會被系統釋放。

回答

3

在代碼的第一位,所述NSMutableData對象在每次循環迭代這避免了任何存儲器問題結束時釋放。

在代碼的第二位,則testDataMethod的返回值是最有可能被自動釋放。由於您的應用程序運行在一個緊密的循環中,autorelease池永遠不會有機會被刷新,因此您很快就會耗盡內存。

試着改變你的代碼的第二位到這一點:

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

感謝,這似乎工作。當我需要向另一個線程發送一個緊密循環時,這是否是標準練習? –

+3

如果您處於可能創建大量自動釋放對象的循環中,則使用「@ autoreleasepool」是常見的(並且基本上是必需的)。這與調度隊列無關。這是一個基本的內存管理問題。長時間運行的循環與許多自動釋放對象一直需要使用autorelease池。無論是否使用ARC,情況都是如此。 – rmaddy

相關問題