Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective-C:在';自我';未设置。。。但事实确实如此_Objective C_Self - Fatal编程技术网

Objective-C:在';自我';未设置。。。但事实确实如此

Objective-C:在';自我';未设置。。。但事实确实如此,objective-c,self,Objective C,Self,我的任务是清理代码库中的一些叮当声错误。我对iPhone开发和Objective C非常陌生,但发现大多数问题都很琐碎。。。这件事让我很难堪,但我肯定这件事让我很尴尬 从ZAttributedString类: - (id)initWithAttributedString:(ZAttributedString *)attr { NSParameterAssert(attr != nil); if ((self = [super init])) { _buffer =

我的任务是清理代码库中的一些叮当声错误。我对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;
}
叮当声警告是“当'self'未设置为'[super或self]init…]的结果时使用实例变量,并突出显示attr的_buffer属性的取消引用”

如果有帮助的话,警告似乎还提到从该方法调用时发现了问题:

- (id)copyWithZone(NSZone *)zone {
    return [(ZAttributedString *)[ZAttributedString allocWithZone:zone] initWithAttributedString:self];
}
有人能给我解释一下这里到底有什么缺陷吗


TIA!

不要使用
->
访问实例变量,尤其是当ivar来自其他对象时

这样做:

_buffer = [[attr string] mutableCopy];
这同样适用于讨厌的
attr->_属性
。显然,zattributestring
attributes`作为私有标头中的属性公开


这个编译器警告看起来确实非常乐观,完全误导,而且很可能在描述上非常错误。提交一个bug来澄清这一点是有用的


请注意,@maddy声称使用
->
直接访问传递的
attr
字符串中的实例变量,因为它的行为类似于复制构造函数,这是不正确的

传入的
attr
可能是
ZAttributedString
实例或子类的实例,或者实际上是实现与
ZAttributedString
相同接口的任何类的实例。因此,您确实必须通过访问器来确保获取正确的状态

现在,作为一个实现细节,
zattributestring
可能要求入站实例是
zattributestring
的非子类实例,但它应该使用
isMemberOfClass:
来声明该要求(请不要这样做)


有时使用直接ivar访问从另一个对象提取状态的唯一地方是
copyWithZone:
的实现,但这是非常脆弱的,经常会导致异常的破坏行为。事实上,
copyWithZone:
(各种plist兼容值类之外)已经充满了脆弱性,并且是许多bug的来源。

您似乎看到了与此完全相同的bug:。它附带了一个非常相似的代码来重现bug

如果在Xcode 4.6.3中运行该代码,您可以验证它是否给出与您看到的相同的错误警告

该错误已通过以下方法解决:

这是固定在主干中的,或者至少大部分是固定的——仍然有一些边缘 警告将触发,但您的项目不会触发的情况

(戴夫,目前所有主要的分析仪工程师都在苹果公司工作,所以 没有真正需要归档副本。不在苹果工作的LLVM人员不需要 有权访问Apple Clang,它随Xcode一起提供,但此修复程序没有成功 Xcode 4.6。您还可以从 )


正如您所见,该错误已修复,但仍然存在于Xcode 4.6中。请等待下一版本的Xcode,分析器警告应该消失。

实际上,此代码来自
zattributestring
类,因此使用
->
从同一类的另一个实例访问IVAR是完全正确的。这适用于当你基本上是在创建一个“复制构造函数”时,这样的代码是不正确的,即使在这种情况下也是如此。如果它是
-copy
方法本身,那么可能(即使这是ObjC历史上的一个非常粗糙的边缘--
NSCopyObject()
也带来了无尽的痛苦)。但不在DI中。该类可能在执行某些操作的getter上具有逻辑,而绑定实例很可能是行为未知的子类。@bbum:“传入属性可能是ZAttributedString实例或子类的实例。”“
self
也可以是子类的实例,因此通过该参数,您永远无法访问实例变量,这显然是错误的。”“不要使用->访问实例变量,尤其是当ivar来自其他对象时。”大多数面向对象语言允许人们访问其他对象的实例变量,他们的教程经常显示这一点。你可能会说这是个坏主意,但总的来说这并不是一件不寻常的事情。@user102008 self与attr的分类完全无关。在init方法中,对象的状态保证是未定义的,因此直接IVAR集是正确的模式,因为子类的初始值设定项尚未执行(通常)。其他语言做什么并不重要。感谢您跟踪llvm错误。有用!