0

我有一个延迟加载的属性,定义如下,每次我访问它时都会保留它,就像foo.bar. 在“for”循环退出(从 init 分派异步)之后,所有的barget 副本都被释放,但与此同时它们都建立起来了,我收到了内存警告。

为什么会这样?ARC 是否永远不会在内部使用 [pool drain] 来清理未使用的内存?还是我以某种方式在调度或块中导致保留周期?

@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
4

1 回答 1

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;
}
于 2013-01-17T10:02:17.730 回答