【问题标题】:Analyzer marks a potential leak for this construct分析器标记此构造的潜在泄漏
【发布时间】:2011-01-24 10:16:55
【问题描述】:

使用以下代码,分析器将 setMyDict 选择器调用标记为潜在泄漏,并在 dealloc 中声明“调用者此时不拥有引用计数的错误递减”

- (id)init {
  if (self = [super init]) {
      [self setMyDict:[[NSMutableDictionary alloc] init]];
  }
  return self;
}

- (void)dealloc {
  [[self myDict] release];
  [super dealloc];
}

@synthesize myDict = _myDict;

我不明白这一点。我认为,通过 alloc init 对象将保留计数增加一,并且指针通过综合属性存储在 _myDict 中。如果我改用这段代码

- (id)init {
  if (self = [super init]) {
    _myDict = [[NSMutableDictionary alloc] init];
  }
  return self;
}

- (void)dealloc {
  [_myDict release];
  [super dealloc];
}

分析器不会抱怨。我错过了什么?

【问题讨论】:

    标签: iphone xcode memory-leaks analyzer


    【解决方案1】:

    @synthesize 为您正在合成的对象提供 setter 和 getter。

    setter 方法看起来像这样(取自 Apple 文档)

    -(void)setMyDict:(NSMutableDictionary *)newDict {
        if (myDict != newDict) {
           [myDict release];
           myDict = [newDict retain];
        }
    }
    

    当你这样做时,你正在制造泄漏:

    [self setMyDict:[[NSMutableDictionary alloc] init]];
    

    因为你永远不会释放新分配的字典。

    解决此问题的方法是:

    NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];
    [self setMyDict:dict];
    [dict release];
    

    这可以解决泄漏问题。

    在dealloc方法中,你应该使用:

    [myDict release]; // Or whatever your property is called.
    

    【讨论】:

    • 我要补充一点,你永远不要在dealloc中使用引用的方法形式。所以,永远不要使用[self getPropertyName]的self.propertyName来释放。如果您的访问器更复杂,这样做会调用可能产生不可预测结果的方法。
    • 或者直接使用[self setMyDict: [NSMutableDictionary dictionary]]
    • 受你真正优秀的 cmets 的启发,我阅读了更多关于属性声明的内容,并发现了 64 位运行时对 ivars 的动态声明。不幸的是,它们不能与 iPhone-Simulator 一起使用。但是如果想减少以后的返工,当该功能可用于模拟器时,应该使用以下内容: init: [self setMyDict: [NSMutableDictionary dictionary]] in dealloc: [self setMyDict:nil]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多