Obj-C,在没有设置为'[(super或self)init ...]的结果时返回'self'?

时间:2011-11-09 22:03:22

标签: objective-c xcode cocoa-touch analyzer

自升级以来,我收到了分析器警告......

Returning 'self' while it is not set to the result of '[(super or self) init...]'

Dunno有什么不对吗?

- (id)initWithFrame:(CGRect)frame {
    if (self == [super initWithFrame:frame]) {
        [self initLayers];
    }
    return self;
}

3 个答案:

答案 0 :(得分:13)

摆脱第二个等号。正确的if语句是:

if(self = [super initWithFrame:frame])

关键在于超级实现可以返回一个不同但仍然有效的对象,而不是self的当前值。在这种情况下,if语句将为false,因为对象不同,因此不会进行初始化。但是,由于它返回了一个不同的对象,超级实现应该释放旧的self,这就是你要返回的内容。这意味着您可能正在返回无效指针。

通过仅使用一个等号,您可以设置变量而不是比较变量。如果if(object)不是object,则nil为真,因此它等同于:

if((self = [super initWithFrame:frame]) != nil)

或者,更易于理解的版本:

self = [super initWithFrame:frame];
if(self != nil)

此代码将self重新指定为超级初始化程序返回的值,而不是仅假设返回的值相同。这就是为什么将变量设置为init...方法而不是alloc的结果很重要的原因。

// good
id object = [[MyClass alloc] init];
// bad
id object = [MyClass alloc];
[object init];

答案 1 :(得分:3)

如果我没记错,语法是self = ...而不是self == ...。语法使用赋值的返回值。

答案 2 :(得分:2)

你的回归自我未初始化

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self initLayers];
    }
    return self;
}