当前位置:  开发笔记 > IOS > 正文

Objective-C Singletons和LLVM/clang泄漏警告

如何解决《Objective-CSingletons和LLVM/clang泄漏警告》经验,为你挑选了2个好方法。

我在应用程序的几个地方使用单例模式,并且clang在分析代码时出现内存泄漏错误.

static MyClass *_sharedMyClass;
+ (MyClass *)sharedMyClass {
  @synchronized(self) {
    if (_sharedMyClass == nil)
      [[self alloc] init];
  }
  return _sharedMyClass;
}

// clang error: Object allocated on line 5 is no longer referenced after this point and has a retain count of +1 (object leaked)

我正在使用这些设置scan-build:

scan-build -v -v -v -V -k xcodebuild

我非常肯定单例中的代码很好 - 毕竟,它与Stack Overflow以及Apple的文档中引用的代码相同 - 但我希望将内存泄漏警告整理出来以便我的扫描 - 建立回报成功.



1> Adam Wright..:

我可能会异常密集,但肯定是你的第5行

[[self alloc] init];

分配一个包含类类型的对象,并迅速抛弃它?你不想要吗?

_sharedMyClass = [[self alloc] init];


然后我猜想CLANG不够聪明,不能推断[self alloc]返回实际上是设置self参数,它将由init方法保存.因此它认为它只是丢失了(正如我所做的那样,没有更多的背景).

2> Justin Ander..:

Apple已经更新了推荐的单例代码以通过静态分析器:

+ (MyGizmoClass*)sharedManager
{
    if (sharedGizmoManager == nil) {
        sharedGizmoManager = [[super allocWithZone:NULL] init];
    }
    return sharedGizmoManager;
}

+ (id)allocWithZone:(NSZone *)zone
{
    return [[self sharedManager] retain];
}

现在+sharedManager调用super -allocWithZone:并分配返回值-init,而singleton -allocWithZone:只返回一个保留的sharedInstance.

编辑:

为什么保留+ allocWithZone:?

+ allocWithZone:被覆盖,因为使用MyGizmoClass的人可以通过调用[[MyGizmoClass alloc] init]而不是[MyGizmoClass sharedManager]来绕过单例.它被保留,因为+ alloc应该始终返回一个保留计数为+1的对象.

每次对+ alloc的调用都应该与-release或-autorelease进行平衡,因此如果没有在+ allocWithZone:中保留,共享实例可能会从其他用户下解除分配.

推荐阅读
手机用户2402852307
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有