【问题标题】:Avoiding static analyzer leak warnings when using objc_msgSend?使用 objc_msgSend 时避免静态分析器泄漏警告?
【发布时间】:2012-04-12 14:55:30
【问题描述】:

我有以下来自通用工厂类的(简化的)代码:

- (id) invokeSetup: (id) object {
    // Just an example, subclasses delegate setup to a component that either returns +0 or +1 references
    return objc_msgSend(object, @selector(init));
}

- (id) newInstance {
    id object = objc_msgSend([NSString class], @selector(alloc));
    id replacement = [self invokeSetup: object];

    return replacement;
}

分析器在return replacement: 上产生警告:

警告:具有 +0 保留计数的对象返回给调用者,其中预期 +1(拥有)保留计数

我需要告诉分析器- invokeSetup 返回的引用是+1。上面的例子被简化了,在实际程序中,有几个约束:

  1. 我不能用 ns_returns_retained 注释 invokeSetup,因为它是继承的,而且还有其他子类 invokeSetup 返回 +0 引用。如果是+1或+0只能在运行时检测到。

  2. 我无法更改任何方法的名称。

  3. 设计就是这样。可能有更好的设计,但这里不能改变。

是否有可能在分配点 (id replacement = ...) 以某种方式告诉 ARC,引用肯定是 +1?

谢谢, 乔辰

【问题讨论】:

  • 我知道你说这是一个例子,但为什么工厂模式试图重新发明/替换alloc & init?为什么init 有时会返回保留? alloc 应该只返回保留,否则创建时某些对象的保留计数将为 2。如果它不是 ARC,那么它会导致代码看起来像 NSString *s = [@"test" newInstance]; [s release]; [s release];。虽然你不能改变它,但无论如何你可以避免它吗?
  • 基本上,您放置的约束排除了所有可能的解决方案,抱歉。好吧,其实我并不抱歉,这看起来是一段非常糟糕的代码。

标签: objective-c automatic-ref-counting


【解决方案1】:

请参阅 https://stackoverflow.com/a/5833430/1313031 了解在代码中抑制静态分析器警告的方法

但是是的,最好的办法是重命名 newInstance

【讨论】:

  • 实际上最好的办法是重写代码以使其不那么糟糕。根据所使用的类或子类,他有一个具有不同所有权语义的方法。用这个写一个稳定的系统是没有希望的。
  • 对不起。重命名只会让生活变得更糟。这是 arc 旨在防止的设计。如果你被这个代码卡住了,那么上面的链接或 -fno-objc-arc 都会隐藏警告,但你仍然会被这个设计卡住。
猜你喜欢
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 1970-01-01
  • 2015-09-01
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多