Три вопроса о конструкторе Objective-C - PullRequest
3 голосов
/ 12 февраля 2010

У меня три быстрых вопроса. Я видел противоречивые ответы, которые, надеюсь, кто-то сможет прояснить.

  • Нужно ли выполнять [super init] вплоть до NSObject? (например, если Foo наследует от NSObject, должен ли Foo вызывать [super init]? Если нет, то это также относится и к dealloc?
  • Происходит ли какая-либо инициализация по умолчанию для переменных-членов в объекте. Например, будет ли инициализирован элемент NSString * нулем? плавать до 0,0?
  • Если у моего объекта есть метод initFoo, могу ли я вызвать [self init] внутри этой функции для выполнения общей инициализации?

С тех пор, как я начал с Objective-C, я предположил, что в первом случае да, а во втором - нет, но я надеюсь сэкономить:

Спасибо

Ответы [ 4 ]

6 голосов
/ 12 февраля 2010

Просто добавлю немного больше к трем ответам, которые меня ожидают:

  1. Да, это так. На практике NSObject (вероятно) не требует этого (сейчас), но если это когда-либо изменилось, вы облажались, если не сделали этого. В любом случае лучше всего привыкнуть (или использовать генерацию кода в XCode, чтобы сбросить шаблон инициализации). Тем не менее, это не всегда init, что вы должны позвонить (более скоро).

  2. Как уже отмечалось, инициализация к значениям по умолчанию (благодаря memcpy 0s, поэтому 0, nil и т. Д.) Гарантирована, и полагаться на это разумно идиоматично. Некоторые люди все еще предпочитают быть явными, и это нормально.

  3. Абсолютно. Запомните init, или любой вариант - это просто нормальный метод. Это всего лишь инициализатор по соглашению (хотя и очень строгое соглашение). Вы можете вызывать другие методы, в том числе другие инициализаторы. Опять же, по соглашению, вы должны выбрать " назначенный инициализатор " и сделать так, чтобы все другие инициализаторы вызывали его. Подумайте об этом в связи с вашим первым вопросом. Если вы подкласс, что будет называть ваш подкласс? По умолчанию автор подкласса будет вызывать ваш init - поэтому, если у вас есть другой назначенный инициализатор, очень важно, чтобы вы сделали это ясно, чтобы авторы подкласса знали, как его вызвать.

Подробнее (авторитетно) вы можете прочитать здесь, в документации Apple .

2 голосов
/ 12 февраля 2010

Вам всегда нужно вызывать метод инициализации суперкласса и присваивать self результату. Вам также определенно необходимо вызвать реализацию super в конце реализации -dealloc.

Все переменные экземпляра по умолчанию инициализируются в ноль / ноль, это гарантировано.

Да, вы можете вызвать [self init] из более конкретного метода инициализации:

- (id)initFoo
{
    self=[self init];
    if(self)
    {
       //do stuff
    }
    return self;
}
0 голосов
/ 12 февраля 2010
  • Да, в противном случае объекты суперкласса не смогут выполнить свою инициализацию.

  • не знаю.

  • Да. Создайте любой метод инициализации, который вы хотите. Документируйте это. Но обязательно вызовите правильный метод инициализации супер: какой бы он ни был.

0 голосов
/ 12 февраля 2010
  1. да для init (не требуется технически, но рекомендуется), безусловно, да для dealloc
  2. да, вся память инициализируется в 0, что составляет nil, 0.0 и т. Д.
  3. да, и это часто встречается
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...