self = [super init] вновь - PullRequest
       33

self = [super init] вновь

3 голосов
/ 04 марта 2012

Я наткнулся на этот пост В Objective-C, почему я должен проверить, если self = [super init] не ноль?

Я могу понять этот синтаксис :

- (id)initWithString:(NSString *)aString
{
    self = [super init];
    if (self)
    {
        instanceString = [aString retain];
    }
    return self;
}

или этот синтаксис :

- (id)init;
{
 if (!(self = [super init]))
   return nil;

 // other stuff
 return self;
}

но я все еще не понимаю "стандартный" синтаксис шаблона

- init {
    if((self = [super init])) {
        // set up instance variables and whatever else here
    }
    return self;
}

Может ли кто-нибудь как можно более четко сказать, что (3) делает более или менее по сравнению с (1) или (2)? Все, что я читаю, так запутанно (почему люди не могут согласиться с чем-то чисто техническим, похоже на политику :))

Тем не менее, когда я читаю статью авторов, и, насколько я могу смутно понять, она выходит далеко за рамки только синтаксической дискуссии о сахаре или вкуса. Например, сказано :

Любопытно, что, хотя случай 3 в подавляющем большинстве случаев более распространен, инициализаторы, которые поддерживают 1, 2 и 4, но несовместимы с делом 3, стали стандартом. К счастью, тогда как случай 3 в подавляющем большинстве случаев более распространен, инициализаторы, поддерживающие 1, 2 и 4, но несовместимы с делом 3, стали стандартом.

Так что я хотел бы получить глубокий философский ответ от Объективных Гуру, если это возможно.

Ответы [ 4 ]

5 голосов
/ 04 марта 2012

Ключом к пониманию (3) является строка if

if((self = [super init])) {

В C каждый оператор имеет возвращаемое значение, вам просто не нужно его использовать.Так как 3 + 4 возвращает 7, оператор = возвращает то же значение, которое было только что присвоено.Это позволяет вам делать с ним интересные вещи:

int a, b, c, d;

a = b = c = d = 5;

(Это работает, потому что оператор имеет ассоциативность справа налево. Это означает, что a = b = 3; эквивалентно a = (b = 3);, поэтому b сначала устанавливается на три, затем a устанавливается на то же значение.)

Итак, теперь мы можем наблюдать, что тест

if((self = [super init])) {

точно такой же, как

self = [super init];
if (self) {

Они все делают одно и то же.Что касается предпочтительного варианта, многие люди думают, что использование выражений в операторах if - плохая практика, так как трудно заметить, что вы к этому не привыкли.Apple, похоже, согласилась с первым примером, который вы перечислили в их шаблонах, а также добавила предупреждение компилятора для первого, если вы попытаетесь сделать это без глупых двойных скобок if(()).

5 голосов
/ 04 марта 2012

Все три выполняют одну и ту же задачу: вызовите [super init], присвойте ей self (в случае, если super's init возвращает другой объект, что в некоторых случаях возможно) и проверьте, равен ли этот возвращаемый указатель нулю.Если это ноль, оставьте, ничего не делая.

Примеры # 1 и # 3 идентичны, они просто слегка переставили синтаксис.# 2 отличается тем, что возвращает явное значение nil, в то время как # 1 и # 3 делают это неявно.

Что использовать - дело вкуса.Я предпочитаю № 2, потому что он сохраняет уровень отступа (мне нравится избегать отступов, если это возможно, потому что, если вы сделали отступ с четырьмя или пятью уровнями, действительно трудно следовать за потоком).какой из них использовать по той же причине, по которой они не могут договориться о том, какой стиль отступов (K & R, Allman, GNU, Whitesmith, ...) использовать: это личное предпочтение и не меняет логику.

1 голос
/ 04 марта 2012

Если у вас есть переменная и нет ==,! =,> Или что-то подобное, выражение будет истинным, если ваша переменная (в данном случае указатель на объект) не равна 0. Это означает, что ваш указатель нене указывает ни на что.nil и NULL определены для 0, поэтому вы можете написать

if ((self = [super init]) != nil) {}

или

if ((self = [super init]) != NULL) {}

или

if ((self = [super init]) != 0) {}

или просто

if ((self = [super init])) {}

тоже.

0 голосов
/ 08 марта 2013

Я также предпочитаю дополнительную «комнату», предоставляемую НЕ с использованием чрезмерно многословного , редко интуитивного ... и откровенно некрасивого синтаксиса, который я вижу в Apple код / ​​по городу и т.д ...

-(id) init {  if (self != super.init) return nil; ...

Я, возможно, тону детей - и заставляю плакать красивых старых индейцев в процессе - но я просто вставляю все это на одну строку ... и не забудьте return self; AOK до сих пор!

...