为什么我的财产没有被释放?

时间:2013-01-09 17:22:40

标签: ios memory-management automatic-ref-counting

我有一个如下定义的延迟加载属性,每次我像foo.bar一样访问它时似乎都会保留。在'for'循环退出(从init调度异步)之后,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

1 个答案:

答案 0 :(得分: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;
}