2013-01-09 38 views
0

我有一个lazily加载的属性定义如下,似乎每次我像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 
+0

“似乎每次我像foo.bar一样访问它时都会保留” - 因为属性太安全了。即使对象本身已被释放,您也可以使用对象的属性(前提是您已在释放对象之前存储属性);这就是为什么getters不做'return _backingIvar;'而是'return [[_backingIvar retain] autorelease];' – 2013-01-09 20:12:41

回答

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; 
}