2

我有一个在终端中运行的脚本,它在我的 iPhone 应用程序上运行扫描构建代码分析器以检查问题。我只是很偶然地注意到,至少有一个实例没有找到未在 dealloc 方法中释放的 IBOutlet ivar。

这是我从终端运行的命令的内容:

#!/bin/sh
cd /Developer/svn/MyCompany/iPhone/MyApplication
scan-build -analyzer-check-dead-stores -analyzer-check-llvm-conventions -analyzer-check-objc-mem -analyzer-check-objc-methodsigs -analyzer-check-objc-missing-dealloc -analyzer-check-objc-unused-ivars -analyzer-check-security-syntactic --experimental-checks -k -V -o scan-reports xcodebuild -configuration Debug -sdk iphonesimulator4.2 clean build

我已经更新到最新版本的 checker,所以不可能有更新版本的 checker。以下是我班级的 .h 文件的相关部分:

@interface LoginWizardUsernameViewController : UIViewController <UITextFieldDelegate, GetUserExistsDidFinish> {

 IBOutlet UITextField *username;
 IBOutlet UIActivityIndicatorView *activityIndicatorView;

}

@property (nonatomic, retain) UITextField *username;
@property (nonatomic, retain) UIActivityIndicatorView *activityIndicatorView;

以下是 .m 文件的相关部分:

// lots o' code omitted here

@implementation LoginWizardUsernameViewController

@synthesize username;
@synthesize activityIndicatorView;

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

如您所见,这两个 IBOutlet 项目没有发布,但即使它们在属性定义中列为保留,检查器由于某种原因没有看到这一点。奇怪的是,我可以去其他类的.m文件,在dealloc方法中注释掉一个release,scan-build在问题扫描结束时愉快地提醒我。我只是无法弄清楚这种特殊情况有什么不同。

4

1 回答 1

4

这是 Clang 静态分析器中的一个错误,由尝试修复不同的问题引起。

根据源代码,Clang 静态分析器将跳过-dealloc检查任何包含非指针 ivars 或IBOutletivars 的类:

104   // Does the class contain any ivars that are pointers (or id<...>)?
105   // If not, skip the check entirely.
106   // NOTE: This is motivated by PR 2517:
107   //        http://llvm.org/bugs/show_bug.cgi?id=2517
108 
109  bool containsPointerIvar = false;
110  
111  for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();
112       I!=E; ++I) {
113 
114    ObjCIvarDecl* ID = *I;
115    QualType T = ID->getType();
116 
117    if (!T->isObjCObjectPointerType() ||
118        ID->getAttr<IBOutletAttr>() || // Skip IBOutlets.
119        ID->getAttr<IBOutletCollectionAttr>()) // Skip IBOutletCollections.
120      continue;
121 
122    containsPointerIvar = true;
123    break;
124  }
125 
126  if (!containsPointerIvar)
127    return;

我怀疑如果您只是将非 IBOutlet 属性添加到您的课程中,它将正常工作。

于 2010-12-21T15:34:20.483 回答