2013-01-09 3 views
0

아래에 정의 된 lazily-loaded 속성이 있습니다.이 값은 foo.bar과 같이 액세스 할 때마다 유지되는 것으로 보입니다. 'for'루프가 종료되면 (init에서 dispatch 된 async) bar의 모든 복사본이 릴리스되지만 그 동안에는 모두 빌드되고 메모리 경고가 발생합니다.내 소유물이 왜 공개되지 않습니까?

왜 이런 일이 발생합니까? ARC는 사용되지 않는 메모리를 정리하기 위해 내부적으로 [수영장 드레인]을 치는 적이 결코 없습니까? 아니면 어떻게 든 내 파견이나 블록에서 유지 사이클을 일으키는 건가요? 풀 오히려 루프 종료 후 미래의 어느 시점에서보다 루프의 모든 반복 한 후 배출되도록

@interface Foo : NSObject 

@property (nonatomic, strong) MyAlgorithm *bar; 

@end 

@implementation Foo 

- (id)init { 

    if (self = [super init]) { 

    __weak Foo *weakSelf = self; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     weakSelf.testAudioFilePaths = [[NSBundle mainBundle] pathsForResourcesOfType:kAudioFileWavType inDirectory:kTestFilesDirectory]; 

     for (NSString *path in weakSelf.testAudioFilePaths) { 

      weakSelf.bar = nil; // this is so we rebuild it for each new path 

      [weakSelf readDataFromAudioFileAtPath:path]; 

     } 

    }); 
    } 
    return self; 
} 

- (MyAlgorithm *)bar { 
    if (!_bar) { 
     _bar = [[MyAlgorithm alloc] initWithBar:kSomeBarConst]; 
    } 
    return _bar; 
} 


@end 
+0

"foo.bar처럼 액세스 할 때마다 유지되는 것 같습니다."- 속성이 너무 안전하기 때문에. 객체의 할당이 해제 된 경우에도 객체의 속성을 사용할 수 있습니다 (객체의 할당을 해제하기 전에 속성을 저장 한 경우). 그래서 getter는'return _backingIvar;를하지 않고''return [[_backingIvar retain] autorelease]; –

답변

0

대답은 @autoreleasepool 블록 루프 내 코드 의 비트를 래핑하는 것입니다 :

- (id)init { 

    if (self = [super init]) { 

    __weak Foo *weakSelf = self; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     weakSelf.testAudioFilePaths = [[NSBundle mainBundle] pathsForResourcesOfType:kAudioFileWavType inDirectory:kTestFilesDirectory]; 

     for (NSString *path in weakSelf.testAudioFilePaths) { 

      @autoreleasepool { 

       weakSelf.bar = nil; // this is so we rebuild it for each new path 

       [weakSelf readDataFromAudioFileAtPath:path]; 
      } 

     } 

    }); 
    } 
    return self; 
} 
관련 문제