Почему не рекомендуется выделять и инициализировать с идентификатором? - PullRequest
7 голосов
/ 16 июля 2011

В следующем примере, какие возможные проблемы могут возникнуть.

id c = [Person alloc];
[c init];

Ответы [ 4 ]

14 голосов
/ 16 июля 2011

Основная проблема с кодом в вашем примере заключается в том, что в некоторых случаях метод -init возвращает объект, отличный от того, который вы создали с помощью + alloc.Если это произойдет, то ваш код будет неправильным, потому что вы не присваиваете результат [c init] для c, и в итоге вы работаете с неправильным объектом (и тем, который не был должным образом инициализирован).Вот почему стандартная идиома состоит в том, чтобы всегда объединять + alloc и -init в одной строке:

id c = [[Person alloc] init];

Теперь вы, возможно, написалиКласс Person и из первых рук знают, что -init всегда возвращает один и тот же объект, но мне не нужно быть близко знакомым с внутренними принципами Person, чтобы прочесть ваш код и понять, является ли он правильным или нет.Ваш код «лучше» в том смысле, что любой может сказать, что он поступает правильно, если вы следуете обычному соглашению.

Я не думаю, что ужасно объявлять c в качестве идентификатора типа, но кажетсяглупо в этом случае.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *Если есть веская причина для использования идентификатора, это нормально, но если вы можете более точно определить тип, вам следует это сделать.

4 голосов
/ 16 июля 2011

При использовании универсального типа id вы не получите предупреждение, если попытаетесь вызвать метод, который не существует.Компилятор предполагает, что вы знаете, что делаете.

В остальном, никаких проблем я не могу придумать.Это часто встречается в нескольких ситуациях (например, быстрое перечисление для гетерогенного типа контейнера)

2 голосов
/ 16 июля 2011

Другая потенциальная опасность состоит в том, что со временем вы можете добавить логику, которая случайно выполняет инициализацию только в определенных случаях ... оставляя объект, который выделен, но никогда не инициализирован, означает, что все значения в нем являются по существу случайными и любой код установки, который он имел в виду сделать не сделано.

0 голосов
/ 16 июля 2011

Прежде всего, проблема приведения типа. Каждый раз, когда вы хотите использовать 'c', вам может понадобиться (Person *), то есть введите его.

во-вторых, если у вас есть какой-либо метод, объявленный в Person, вы не можете назвать его как стиль [c aMthod], вы должны использовать, [(Person *) c aMethod].

...