2013-10-30 1 views
0

대학 프로젝트 용 Objective-C에 명령 줄 응용 프로그램을 작성하려고합니다. 프로젝트는 행렬 조작이 필요하므로 모든 행렬 메소드 (더하기와 곱셈 등)를 처리하는 클래스를 작성했습니다. 내 매트릭스 방법은 다음과 같이 : 아이폰 OS는 ARC가 문제없이 내 모든 메모리 할당과 해제를 처리하는 기대에 대한 NSArray가 ARC에서 할당 해제되지 않았습니다. Objective-C

- (NSArray *)sumMatrices:(NSArray *)matrices 
{ 
    NSMutableArray *sum = [[NSMutableArray alloc] init]; 

    NSInteger cols = [matrices[0][0] count]; 
    NSInteger rows = [matrices[0] count]; 

    for (int i = 0; i < rows; i++) { 

     NSMutableArray *row = [[NSMutableArray alloc] init]; 

     for (int j = 0; j < cols; j++) { 

      CGFloat value = 0.0; 

      for (NSArray *array in matrices) { 
       value += [array[i][j] doubleValue]; 
      } 

      [row addObject:[NSNumber numberWithDouble:value]]; 

     } 

     [sum addObject:[row copy]]; 
     row = nil; 

    } 

    return [sum copy]; 

} 

그러나 프로그래머

이 프로그램에 엄청난 문제가,이 경우 그러나, 목표 - C를 사용하는 데 NSMutableArray 'sum'은 절대 할당 해제되지 않으며이 메서드는 수천 번 실행되는 루프에서 호출되기 때문에 (RK4를 사용하여 이중 진자 모델링) 메모리 사용량이 늘어나고 프로그램이 매우 느려집니다.

이 메서드가 반환 된 후에 NSMutableArray이 할당 해제되지 않는 이유가 있습니까? 많은 세부 사항으로가는없이

+0

for 루프로 작성 했으므로 배열에 많은 시간 값이 추가 될 수 있습니다. –

+0

할당되지 않은 배열은 어느 것입니까? 원본'sum' 또는 반환 할 사본? 반환 값을 지키고있는 것은 무엇입니까? –

+1

그것은 당신이 원하는 것을하는 데 매우 비효율적 인 것처럼 보입니다. 'NSNumber' 객체를 다루는 것은 고통 스럽기 때문에'float's의 2 차원 배열 인'malloc()'을 사용한다고 말할 수 있습니다. * 길 * 더 빠를 것입니다. – trojanfoe

답변

1

문제는이 코드와 그 코드를 둘러싼 코드에 관한 것보다 적습니다. 잠시 동안 주위에 코드가 다음과 같이 있다고 가정 해 보겠습니다.

NSArray *matricies; //Declared somewhere else; 
NSMutableArray *results = [[NSMutableArray alloc] init]; 

for (int i=0; i < [matricies count] - 1; i++) { 
    for (int j=i+1; j < [matricies count]; i++) { 
     NSArray *sum = [self sumMatrices:@[matricies[i], matricies[j]]]; 
     [results addObject:sum]; 
    } 
} 

실제 수행하는 작업은이 예제와 관련이 없습니다. 코드 패턴은입니다. 중첩 된 "tight"루프를 사용하고 있음을 알 수 있습니다. 컨트롤은 모든 계산이 완료 될 때까지 실행 루프로 돌아 가지 않습니다. ARC가 없으면 자동 회수 된 객체를 제외하고 마지막 release이 수행되는 즉시 메모리가 해제됩니다. ARC를 사용하면 autoreleased 오브젝트와 거의 같은 방식으로 컨트롤이 runloop으로 반환 될 때까지 메모리가 해제되지 않습니다. 결과적으로 처리가 완료되고 시스템에서 메모리를 해제해야한다고 결정할 때까지 코드가 유출 된 것처럼 보입니다. CPU가 끊임없이 과부하 상태가되면 절대적으로 수행해야 할 때까지 메모리를 정리하지 못할 수 있습니다.

이 경우 도움을주기 위해 @autoreleasepool을 사용하는 몇 가지 방법이 있지만 코드가 상당히 느려질 수 있습니다. 또한 Objective C는 객체 및 메서드 호출에 대해 상당히 느린 언어입니다. 이 코드를 많이 사용하는 경우 C 또는 C++로 변환하고 직접 메모리를 관리해야합니다.

+0

나는 내가 당신의 충고를 받아서 C++을 사용하도록 바꿀 것이라고 생각한다. 이것은 가치가있는 것보다 엉덩이에 더 많은 고통을주는 것 같다. – simonthumper

0

당신은 내가 수정됩니다하지만 경우에 당신이 정말로 그것을 필요합니까 배열을 유지하려면 내가 사본을 사용 autoreleasepool

https://developer.apple.com/library/mac/documentation/cocoa/conceptual/memorymgmt/articles/mmAutoreleasePools.html

를 사용하려고 할 수 있습니까?

+0

autoreleasepool 블록에서 각 메서드를 중첩 시키려고했지만 성공하지 못했습니다. – simonthumper

+0

for-loop에서 시도 했습니까? (for-command 바로 뒤에) –

+0

예, 행운을 빌어 요 autorelease 블록에 아무것도 넣지 마십시오 ... :/심지어 autorelease 블록에서 main.m의 기본 메소드를 래핑하더라도 여전히 빌드됩니다 – simonthumper