我的任务是清除代码库中的一些Clang错误。我对iPhone开发和Objective C非常陌生,但是发现大多数问题都是微不足道的......当我确定它有些令人尴尬时,这个问题让我很难过。
来自ZAttributedString类:
- (id)initWithAttributedString:(ZAttributedString *)attr {
NSParameterAssert(attr != nil);
if ((self = [super init])) {
_buffer = [attr->_buffer mutableCopy];
_attributes = [[NSMutableArray alloc] initWithArray:attr->_attributes copyItems:YES];
}
return self;
}
clang警告是“当'self'未设置为'[super或self] init ...]'的结果时使用的实例变量,并且attr的_buffer属性的解除引用被突出显示。
如果有帮助,警告似乎也提到在使用此方法调用时发现问题:
- (id)copyWithZone(NSZone *)zone {
return [(ZAttributedString *)[ZAttributedString allocWithZone:zone] initWithAttributedString:self];
}
任何人都可以向我解释这里的缺陷究竟是什么?
TIA!
答案 0 :(得分:4)
当ivar来自其他对象时,不要使用->
来访问实例变量,尤其是。
这样做:
_buffer = [[attr string] mutableCopy];
同样令人讨厌的attr->_attributes
。显然,ZAttributedString exposes
属性`作为私有头中的属性。
编译器警告似乎确实看起来非常乐观,完全具有误导性,而且很可能是错误的描述。提交一份错误以澄清这一点会很有用。
请注意,@ maddy声称使用->
直接在传递的attr
字符串中访问实例变量,因为它像复制构造函数一样不正确。
传入的attr
可以是ZAttributedString
实例或子类的实例,或者实际上是实现与ZAttributedString
相同的接口的任何类的实例。因此,你真的必须通过访问者来保证你正在抓住正确的状态。
现在,作为一个实现细节,ZAttributedString
可能要求入站实例是ZAttributedString
的非子类化实例,但它应该使用isMemberOfClass:
断言要求(并且,请不要这样做)。
直接ivar访问有时用于从另一个对象中提取状态的唯一地点是copyWithZone:
的实现,但这非常脆弱,并且导致破坏性行为。实际上,copyWithZone:
(在各种plist兼容值类之外)充斥着脆弱性和许多错误的来源。
答案 1 :(得分:2)
您似乎看到了与此完全相同的错误:"[Bug 15092] New: static analyzer false positive: reports instance variable used while 'self' is not set to the result of [(super or self)] init"。它有一个非常相似的代码来重现bug。
如果您在Xcode 4.6.3中运行该代码,您可以验证它是否提供了与您所看到的相同的错误警告。
使用comment解决了错误:
这是固定在行李箱中,或至少大部分是固定的 - 还有一些优势 警告会触发的情况,但不是你的项目。
(戴夫,现在所有主要的分析仪工程师都在Apple工作,所以有 没有真正需要文件重复。不在Apple工作的LLVM人员不会 可以访问随Xcode一起提供的Apple Clang,而这个修复程序没有 Xcode 4.6。您还可以从中获取更新的检查器构建 http://clang-analyzer.llvm.org)
正如您所看到的,错误已修复但仍存在于Xcode 4.6中。坚持下一个版本的Xcode,分析仪警告应该消失。