Obj-C, возвращая 'self', пока оно не установлено как результат '[(super или self) init ...]'? - PullRequest
3 голосов
/ 10 ноября 2011

Я получаю предупреждение анализатора после обновления ...

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

Не знаю, что с ним не так?

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

Ответы [ 3 ]

13 голосов
/ 10 ноября 2011

Избавьтесь от второго знака равенства. Правильный оператор if:

if(self = [super initWithFrame:frame])

Суть в том, что супер реализация может вернуть другой, но все же действительный объект, отличный от текущего значения self. В этом случае ваш оператор if будет ложным, поскольку объекты различны, и поэтому ваша инициализация не произойдет. Однако, поскольку он возвратил другой объект, супер реализация должна была освободить старое «я», которое вы и возвращаете. Это означает, что вы, вероятно, возвращаете неверный указатель.

Используя только один знак равенства, вы устанавливаете переменную, а не сравниваете ее. Так как 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];
3 голосов
/ 10 ноября 2011

Если я правильно помню, синтаксис будет self = ..., а не self == ....Синтаксис использует возвращаемое значение из присваивания.

2 голосов
/ 10 ноября 2011

ваше возвращение не инициализировано

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