2014-01-21 5 views
0

그래서 NSImage의 전체 묶음을 만드는 NSThread에서 실행되는 코드가 있습니다. 각 이미지의 작은 부분이 다른 NSImage에 그려지고 스레드가 종료됩니다. 이 작업이 완료되면drawInRect는 향후 어느 시점까지 NSImage를 유지합니까?

그래서,

NSImage *outputImage = [[NSImage alloc] initWithSize:size]; 
[outputImage lockFocus]; 
while(1000 times) 
    NSImage* image = [[NSImage alloc] initWithSize:size]; 
    ... image is processed ... 
    [image drawInRect: ... fromRect: ... ] 
[outputImage unlockFocus]; 

같은이 스레드는 뷰에 배치하도록 메인 스레드로 다시 만들어 NSImage을 보내 performSelectorOnMainThread를 사용합니다.

이 모든 것이 정상적으로 작동하며 최종 이미지는 정확히 예상대로입니다. 그러나 루프가 진행되는 동안 응용 프로그램의 메모리 사용량은 선형으로 증가합니다. 각 NSImage은 나중에 다시 릴리스되지 않습니다. 내 이론은 drawInRect 호출이 어딘가에 파이프 라인되고 실제로 나중에 실행되지 않는다는 것입니다. 이 올바른지? 그리고 만약 그렇다면 어떻게 그것을 막을 수 있습니까? 루프 카운터를 너무 크게 만들면 응용 프로그램이 중단되어 문제가 발생합니다.

나는 루프로 포커스의 잠금 및 잠금 해제를 시도했지만 아무런 차이가 없었다.

drawInRect 호출 만 꺼내면 메모리 사용량이 스레드의 수명 동안 평탄한 것으로 확인되었습니다. 기억이 올라간다는 부름을 들어야 만합니다.

저는이 프로젝트에서 ARC를 사용하고 (분명히?) OSX10.9에서 실행 중입니다.

답변

2

NSImages가 어느 시점에서 자동 복구 풀에 추가되는 것처럼 들립니다. 그들은 수영장이 흘러 나올 때까지 보통 내뿜 지 않을 것입니다.

당신이 당신의 자신의 오토 릴리즈 풀을 만들고 싶어이 같은 인스턴스에서

:이 모든 패스를 배출 얻을 것이다 서브 풀을 생성

NSImage *outputImage = [[NSImage alloc] initWithSize:size]; 
[outputImage lockFocus]; 
while(1000 times) { 
    @autoreleasepool { 
     NSImage* image = [[NSImage alloc] initWithSize:size]; 
     ... image is processed ... 
     [image drawInRect: ... fromRect: ... ] 
    } 
} 
[outputImage unlockFocus]; 

을 당신의 거대한 축적이되지 않도록 이미지.

+0

고맙습니다. 아마도 그럴 것입니다. 나는 흥미 롭다. 나는 boost :: shared_pointers를 사방에 (예 : C++ 배경에서) 사용하는 것과 같이 많이 사용하는 자동 참조 계산을 사용한다고 가정했다. 그래서 일단 무언가가 범위를 벗어나거나 null이 할당되면 해제 될 것입니다. 나는 당신의 의견에서 이것이 ARC의 경우가 아니라고 가정하고, 이것을 실현하기 위해 명시 적으로 특수 블록을 선언해야한다. –

+0

나는 autoreleasing을 완전히 피할 수있는 경우가 있다고 믿습니다. 실제로이 경우에 코드에서 트리거 된 것이 무엇인지 확신 할 수 없습니다. 실제로 당신을 아프게합니다. –

+0

지난 밤에이 픽스를 시도했는데 문제가 완전히 지워졌습니다. 물론 drawInRect를 호출하지 않으면 문제를 예방할 수 있다는 점은 흥미 롭습니다. 물론 코드에서 아무 것도하지 못하도록 막을 수도 있습니다. 필요할 때마다 @autorelease를 사용하는 것을 기억해야합니다. 당신의 도움을 주셔서 감사합니다. –