适当的,内存管理的自定义NSDictionary getter实现

时间:2011-10-14 00:26:54

标签: iphone ios memory-management getter-setter

提前致谢...

所以在最近的一些内存泄漏和错误(记录here)之后,我一直在研究我的内存管理,现在我正在尝试在一个帮助类中为NSDictionary编写一个自定义的getter

自定义getter的原因是:

首先,它是一个计算字典,所以对于性能问题,我想返回缓存对象,除非有必要重新生成它(我的下面的例子计算成本太高,但是类中的其他人将会这样)。

其次,我想懒惰地实例化。我只想生成字典,如果另一个类“问”它,这就是我在getter中检查nil的原因。

所以,问题。下面的代码代表我第一次(学习)尝试编写自定义setter / getter,我通常只是合成。

1)这是正确的实施和适当的内存管理吗?

2)这是最好的吗?

3)BOOL installedStandardsChangedSinceLastRead是标记需要重新计算的最佳方法吗?如果类中的其他方法发生了某些变化,就会发生这种情况。但是,我应该将这些方法改为_installedStandards而不是,因为这也会触发重新计算?

4)最后,如果我确实只是让其他方法将iVar标记为重新计算,我将如何确保不泄漏?我会使用setter(即self.installedStandards = nil),直接使用iVar(即_installedStandards = nil)还是其他东西?

(哦,如果我直接对iVar进行了修改,我是否需要先发布它?看起来正确的是[_installedStandards release]; _installedStandards = nil?在这种情况下我不能只使用self.installedStandards = nil ?)

代码! 提醒一下,这是一个更复杂的类(见顶部链接)的简化版本,其中包含许多这些setter / getter。在充实它之前,我需要确保我正确执行。

.h文件

@interface InstalledStandardTracker20 : NSObject {

    NSDictionary *_installedStandards;
    BOOL _installedStandardsChangedSinceLastRead;
}

@property (nonatomic, retain) NSDictionary *installedStandards;
@property (nonatomic) BOOL installedStandardsChangedSinceLastRead;

@end

@implementation

@implementation InstalledStandardTracker20

@synthesize installedStandardsChangedSinceLastRead = _installedStandardsChangedSinceLastRead;

- (void)refreshInstalledStandards {
    NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
    self.installedStandards = [currentDefaults objectForKey:@"installedStandards"];
    self.installedStandardsChangedSinceLastRead = NO;
}

- (NSDictionary *)installedStandards {
    if (!_installedStandards || self.installedStandardsChangedSinceLastRead) {
        [self refreshInstalledStandards];
    }
    return _installedStandards;
}

- (void)setInstalledStandards:(NSDictionary *)newInstalledStandards {
    [newInstalledStandards retain];
    [_installedStandards release];
    _installedStandards = newInstalledStandards;
}

1 个答案:

答案 0 :(得分:0)

这个问题很难回答,因为班级之外没有任何背景。代码似乎没有内存泄漏。此外,您不需要实现-setInstalledStandards:。由于您在retain属性上调用@synthesize,因此生成的setter看起来就像那样。从本质上讲,您使用完全相同的方法覆盖该方法。

对于您的其他问题,将iVar取出与内存中保存的对象无关。一旦释放iVar,指针中包含的内存地址对象就不再保证存在。通过nilling iVar,您只需将该内存地址重置为nil即可。这可以避免您获得EXC_BAD_ACCESS运行时异常,因为程序的其他任何部分都不会尝试访问此未定义的地址空间。

从本质上讲,你总是要释放它。虽然nilling是一种很好的做法,但只要你知道它在内存中包含一个有效的对象,你就不会尝试访问它。我希望这是有道理的。