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 pool은 결코 플러시 될 기회가 주어지지 않으므로 빠르게 메모리가 부족합니다. 여기에 코드의 두 번째 비트를 변경

시도 :

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

덕분에, 제대로 작동 않습니다. 타이트한 루프를 다른 스레드로 보내야 할 때 표준 실행입니까? –

+3

'@ autoreleasepool '을 사용하는 것은 당신이 많은 자동 회수 객체를 만들 수있는 루프에있는 경우에 공통적으로 (그리고 기본적으로 필요하다). 이는 디스패치 대기열과 아무 관련이 없습니다. 기본적인 메모리 관리 문제입니다. autoreleased 오브젝트가 많은 장기 실행 루프는 항상 autorelease 풀을 사용해야합니다. 이는 ARC가 있든 없든 마찬가지입니다. – rmaddy